-
-
Notifications
You must be signed in to change notification settings - Fork 159
Expand file tree
/
Copy pathregistry.ts
More file actions
77 lines (62 loc) · 2.16 KB
/
Copy pathregistry.ts
File metadata and controls
77 lines (62 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { domainOf } from "./domain.ts"
import { throwInternalError } from "./errors.ts"
import { isomorphic } from "./isomorphic.ts"
import { FileConstructor, objectKindOf } from "./objectKinds.ts"
// Eventually we can just import from package.json in the source itself
// but for now, import assertions are too unstable and it wouldn't support
// recent node versions (https://nodejs.org/api/esm.html#json-modules).
// For now, we assert this matches the package.json version via a unit test.
export const arkUtilVersion = "0.56.1"
export const initialRegistryContents = {
version: arkUtilVersion,
filename: isomorphic.fileName(),
FileConstructor
}
export type InitialRegistryContents = typeof initialRegistryContents
export interface ArkRegistry extends InitialRegistryContents {
[k: string]: unknown
}
export const registry: ArkRegistry = initialRegistryContents as never
declare global {
export interface ArkEnv {
prototypes(): never
}
export namespace ArkEnv {
export type prototypes = ReturnType<ArkEnv["prototypes"]>
}
}
const namesByResolution = new Map<object | symbol, string>()
const nameCounts: Record<string, number | undefined> = Object.create(null)
export const register = (value: object | symbol): string => {
const existingName = namesByResolution.get(value)
if (existingName) return existingName
let name = baseNameFor(value)
if (nameCounts[name]) name = `${name}${nameCounts[name]!++}`
else nameCounts[name] = 1
registry[name] = value
namesByResolution.set(value, name)
return name
}
export const isDotAccessible = (keyName: string): boolean =>
/^[$A-Z_a-z][\w$]*$/.test(keyName)
const baseNameFor = (value: object | symbol) => {
switch (typeof value) {
case "object": {
if (value === null) break
const prefix = objectKindOf(value) ?? "object"
// convert to camelCase
return prefix[0].toLowerCase() + prefix.slice(1)
}
case "function":
return isDotAccessible(value.name) ? value.name : "fn"
case "symbol":
return value.description && isDotAccessible(value.description) ?
value.description
: "symbol"
}
return throwInternalError(
`Unexpected attempt to register serializable value of type ${domainOf(
value
)}`
)
}