@lukekaalim/act-backstage 3.1.0 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/mod.ts +1 -0
- package/package.json +3 -3
- package/registry.ts +142 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @lukekaalim/act-backstage
|
|
2
2
|
|
|
3
|
+
## 3.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- bf3138f: Added PrimitiveRegistry for dynamically adding more elements to act-three, implemented in backstage
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [bf3138f]
|
|
12
|
+
- @lukekaalim/act@4.3.0
|
|
13
|
+
|
|
14
|
+
## 3.1.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @lukekaalim/act-recon@4.0.0
|
|
20
|
+
- @lukekaalim/act@4.2.0
|
|
21
|
+
|
|
3
22
|
## 3.1.0
|
|
4
23
|
|
|
5
24
|
### Minor Changes
|
package/mod.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lukekaalim/act-backstage",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "mod.ts",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@lukekaalim/act": "^4.
|
|
8
|
-
"@lukekaalim/act-recon": "^
|
|
7
|
+
"@lukekaalim/act": "^4.3.0",
|
|
8
|
+
"@lukekaalim/act-recon": "^4.0.0"
|
|
9
9
|
}
|
|
10
10
|
}
|
package/registry.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Element, ElementType, h, Props, Ref } from "@lukekaalim/act";
|
|
2
|
+
|
|
3
|
+
export const createPrimitiveRegistry = <PropsMap extends {}, Base>() => {
|
|
4
|
+
type AnyType = keyof PropsMap;
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// Defined inside the function to avoid
|
|
8
|
+
// passing a headache full of generics
|
|
9
|
+
type PrimitiveRegistry = {
|
|
10
|
+
registerPrimitive<Type extends AnyType, Primitive extends Base>(
|
|
11
|
+
type: Type,
|
|
12
|
+
createHandler: (initial: PropsMap[Type]) => Primitive,
|
|
13
|
+
updateHandler: (instance: Primitive, next: PropsMap[Type], prev:PropsMap[Type]) => void,
|
|
14
|
+
): PrimitiveRegistry,
|
|
15
|
+
|
|
16
|
+
addGlobalCreateHandler(handler: GlobalCreateHandler): PrimitiveRegistry;
|
|
17
|
+
addGlobalUpdateHandler(handler: GlobalUpdateHandler): PrimitiveRegistry;
|
|
18
|
+
registerUnhandledPrimitives(types: AnyType[]): PrimitiveRegistry;
|
|
19
|
+
|
|
20
|
+
create(element: Element): null | Base,
|
|
21
|
+
update(instance: Base, next: Element, prev: null | Element): void,
|
|
22
|
+
|
|
23
|
+
elements: { [Type in AnyType]: ElementType<PropsMap[Type] extends Props ? PropsMap[Type] : {}> },
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
type PrimitiveHandler = {
|
|
27
|
+
type: keyof PropsMap,
|
|
28
|
+
createHandler: (initial: PropsMap[keyof PropsMap]) => Base,
|
|
29
|
+
updateHandler: (instance: Base, next: PropsMap[keyof PropsMap], prev:PropsMap[keyof PropsMap]) => void,
|
|
30
|
+
}
|
|
31
|
+
type GlobalCreateHandler = (type: AnyType, initial: PropsMap[AnyType]) => null | Base;
|
|
32
|
+
type GlobalUpdateHandler = (type: AnyType, instance: Base, next: PropsMap[AnyType], prev:PropsMap[AnyType]) => void;
|
|
33
|
+
|
|
34
|
+
const primitiveHandlers: Map<keyof PropsMap, PrimitiveHandler> = new Map();
|
|
35
|
+
const globalCreateHandlers: GlobalCreateHandler[] = [];
|
|
36
|
+
const globalUpdateHandlers: GlobalUpdateHandler[] = [];
|
|
37
|
+
|
|
38
|
+
const registry: PrimitiveRegistry = {
|
|
39
|
+
registerPrimitive(type, createHandler, updateHandler) {
|
|
40
|
+
primitiveHandlers.set(type, { type, createHandler: createHandler as any, updateHandler: updateHandler as any });
|
|
41
|
+
(registry.elements as any)[type] = type;
|
|
42
|
+
return registry;
|
|
43
|
+
},
|
|
44
|
+
registerUnhandledPrimitives(types) {
|
|
45
|
+
for (const type of types) {
|
|
46
|
+
(registry.elements as any)[type] = type;
|
|
47
|
+
}
|
|
48
|
+
return registry;
|
|
49
|
+
},
|
|
50
|
+
addGlobalCreateHandler(handler) {
|
|
51
|
+
globalCreateHandlers.push(handler);
|
|
52
|
+
return registry;
|
|
53
|
+
},
|
|
54
|
+
addGlobalUpdateHandler(handler) {
|
|
55
|
+
globalUpdateHandlers.push(handler);
|
|
56
|
+
return registry;
|
|
57
|
+
},
|
|
58
|
+
create(element) {
|
|
59
|
+
const handler = primitiveHandlers.get(element.type as any);
|
|
60
|
+
if (handler) {
|
|
61
|
+
return handler.createHandler(element.props as any);
|
|
62
|
+
}
|
|
63
|
+
for (const globalHandler of globalCreateHandlers) {
|
|
64
|
+
const instance = globalHandler(element.type as any, element.props as any)
|
|
65
|
+
if (instance)
|
|
66
|
+
return instance;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
},
|
|
70
|
+
update(instance, next, prev) {
|
|
71
|
+
const handler = primitiveHandlers.get(next.type as any);
|
|
72
|
+
if (handler) {
|
|
73
|
+
handler.updateHandler(instance as any, next.props as any, prev && prev.props as any);
|
|
74
|
+
}
|
|
75
|
+
for (const globalHandler of globalUpdateHandlers) {
|
|
76
|
+
globalHandler(next.type as any, instance, next.props as any, prev && prev.props as any);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
elements: {} as any,
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return registry;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Users can write:
|
|
87
|
+
* ```ts
|
|
88
|
+
* declare module "@lukekaalim/act-three" {
|
|
89
|
+
* interface ExtendedPrimitives {
|
|
90
|
+
* MyPrimitive: { myProps: boolean }
|
|
91
|
+
* }
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
* to add a new type definition for an element,
|
|
95
|
+
* and then supply an implementation via:
|
|
96
|
+
*
|
|
97
|
+
* ```ts
|
|
98
|
+
* registry
|
|
99
|
+
* .registerPrimitive(
|
|
100
|
+
* 'MyPrimitive',
|
|
101
|
+
* () => new MyPrimitive(),
|
|
102
|
+
* (primitive, props) => { primitive.myProps = props.myProps; })
|
|
103
|
+
* );
|
|
104
|
+
*
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
interface ExtendedPrimitives {
|
|
108
|
+
}
|
|
109
|
+
type BuiltinPrimitives = {
|
|
110
|
+
div: {}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
type AllPrimitives = BuiltinPrimitives & ExtendedPrimitives;
|
|
114
|
+
|
|
115
|
+
const test = createPrimitiveRegistry<AllPrimitives, HTMLElement | MyExtensionClass>()
|
|
116
|
+
.registerPrimitive('button', () => new MyExtensionClass(), (instance) => {
|
|
117
|
+
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
const test2 = createPrimitiveRegistry<{ red: { hi: true } }, MyCompetingPrimitive>()
|
|
122
|
+
.registerPrimitive('red', () => new MyCompetingPrimitive(), (instance) => {
|
|
123
|
+
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
h(test.elements.div, { innerText: 'hello', ref: { current: null } })
|
|
127
|
+
h(test.elements.button, { onClick: console.log })
|
|
128
|
+
h(test2.elements.red, { hi: true })
|
|
129
|
+
|
|
130
|
+
const a3 = test2.elements;
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
interface ExtendedPrimitives {
|
|
134
|
+
button: { onClick?: () => void },
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
class MyExtensionClass {
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
class MyCompetingPrimitive {
|
|
141
|
+
hi = true;
|
|
142
|
+
}
|