@lynx-js/genui 0.0.1-rc.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/LICENSE +202 -0
- package/README.md +170 -0
- package/a2ui/README.md +140 -0
- package/a2ui/dist/catalog/Button/catalog.json +156 -0
- package/a2ui/dist/catalog/Button/index.d.ts +35 -0
- package/a2ui/dist/catalog/Button/index.js +35 -0
- package/a2ui/dist/catalog/Button/index.js.map +1 -0
- package/a2ui/dist/catalog/Card/catalog.json +24 -0
- package/a2ui/dist/catalog/Card/index.d.ts +11 -0
- package/a2ui/dist/catalog/Card/index.js +19 -0
- package/a2ui/dist/catalog/Card/index.js.map +1 -0
- package/a2ui/dist/catalog/CheckBox/catalog.json +170 -0
- package/a2ui/dist/catalog/CheckBox/index.d.ts +32 -0
- package/a2ui/dist/catalog/CheckBox/index.js +24 -0
- package/a2ui/dist/catalog/CheckBox/index.js.map +1 -0
- package/a2ui/dist/catalog/Column/catalog.json +57 -0
- package/a2ui/dist/catalog/Column/index.d.ts +15 -0
- package/a2ui/dist/catalog/Column/index.js +55 -0
- package/a2ui/dist/catalog/Column/index.js.map +1 -0
- package/a2ui/dist/catalog/Divider/catalog.json +14 -0
- package/a2ui/dist/catalog/Divider/index.d.ts +9 -0
- package/a2ui/dist/catalog/Divider/index.js +8 -0
- package/a2ui/dist/catalog/Divider/index.js.map +1 -0
- package/a2ui/dist/catalog/Icon/catalog.json +45 -0
- package/a2ui/dist/catalog/Icon/index.d.ts +14 -0
- package/a2ui/dist/catalog/Icon/index.js +11 -0
- package/a2ui/dist/catalog/Icon/index.js.map +1 -0
- package/a2ui/dist/catalog/Image/catalog.json +62 -0
- package/a2ui/dist/catalog/Image/index.d.ts +16 -0
- package/a2ui/dist/catalog/Image/index.js +30 -0
- package/a2ui/dist/catalog/Image/index.js.map +1 -0
- package/a2ui/dist/catalog/LineChart/catalog.json +98 -0
- package/a2ui/dist/catalog/LineChart/index.d.ts +31 -0
- package/a2ui/dist/catalog/LineChart/index.js +195 -0
- package/a2ui/dist/catalog/LineChart/index.js.map +1 -0
- package/a2ui/dist/catalog/List/catalog.json +52 -0
- package/a2ui/dist/catalog/List/index.d.ts +15 -0
- package/a2ui/dist/catalog/List/index.js +53 -0
- package/a2ui/dist/catalog/List/index.js.map +1 -0
- package/a2ui/dist/catalog/Modal/catalog.json +18 -0
- package/a2ui/dist/catalog/Modal/index.d.ts +12 -0
- package/a2ui/dist/catalog/Modal/index.js +33 -0
- package/a2ui/dist/catalog/Modal/index.js.map +1 -0
- package/a2ui/dist/catalog/PieChart/catalog.json +87 -0
- package/a2ui/dist/catalog/PieChart/index.d.ts +37 -0
- package/a2ui/dist/catalog/PieChart/index.js +131 -0
- package/a2ui/dist/catalog/PieChart/index.js.map +1 -0
- package/a2ui/dist/catalog/RadioGroup/catalog.json +184 -0
- package/a2ui/dist/catalog/RadioGroup/index.d.ts +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js +36 -0
- package/a2ui/dist/catalog/RadioGroup/index.js.map +1 -0
- package/a2ui/dist/catalog/Row/catalog.json +57 -0
- package/a2ui/dist/catalog/Row/index.d.ts +15 -0
- package/a2ui/dist/catalog/Row/index.js +28 -0
- package/a2ui/dist/catalog/Row/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/catalog.json +183 -0
- package/a2ui/dist/catalog/Slider/index.d.ts +41 -0
- package/a2ui/dist/catalog/Slider/index.js +39 -0
- package/a2ui/dist/catalog/Slider/index.js.map +1 -0
- package/a2ui/dist/catalog/Slider/utils.d.ts +11 -0
- package/a2ui/dist/catalog/Slider/utils.js +58 -0
- package/a2ui/dist/catalog/Slider/utils.js.map +1 -0
- package/a2ui/dist/catalog/Tabs/catalog.json +28 -0
- package/a2ui/dist/catalog/Tabs/index.d.ts +12 -0
- package/a2ui/dist/catalog/Tabs/index.js +32 -0
- package/a2ui/dist/catalog/Tabs/index.js.map +1 -0
- package/a2ui/dist/catalog/Text/catalog.json +74 -0
- package/a2ui/dist/catalog/Text/index.d.ts +18 -0
- package/a2ui/dist/catalog/Text/index.js +27 -0
- package/a2ui/dist/catalog/Text/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/catalog.json +147 -0
- package/a2ui/dist/catalog/TextField/index.d.ts +35 -0
- package/a2ui/dist/catalog/TextField/index.js +43 -0
- package/a2ui/dist/catalog/TextField/index.js.map +1 -0
- package/a2ui/dist/catalog/TextField/utils.d.ts +7 -0
- package/a2ui/dist/catalog/TextField/utils.js +51 -0
- package/a2ui/dist/catalog/TextField/utils.js.map +1 -0
- package/a2ui/dist/catalog/defineCatalog.d.ts +119 -0
- package/a2ui/dist/catalog/defineCatalog.js +196 -0
- package/a2ui/dist/catalog/defineCatalog.js.map +1 -0
- package/a2ui/dist/catalog/index.d.ts +20 -0
- package/a2ui/dist/catalog/index.js +26 -0
- package/a2ui/dist/catalog/index.js.map +1 -0
- package/a2ui/dist/catalog/utils/chart.d.ts +3 -0
- package/a2ui/dist/catalog/utils/chart.js +28 -0
- package/a2ui/dist/catalog/utils/chart.js.map +1 -0
- package/a2ui/dist/functions/index.d.ts +19 -0
- package/a2ui/dist/functions/index.js +87 -0
- package/a2ui/dist/functions/index.js.map +1 -0
- package/a2ui/dist/index.d.ts +11 -0
- package/a2ui/dist/index.js +35 -0
- package/a2ui/dist/index.js.map +1 -0
- package/a2ui/dist/react/A2UI.d.ts +77 -0
- package/a2ui/dist/react/A2UI.js +159 -0
- package/a2ui/dist/react/A2UI.js.map +1 -0
- package/a2ui/dist/react/A2UIProvider.d.ts +25 -0
- package/a2ui/dist/react/A2UIProvider.js +20 -0
- package/a2ui/dist/react/A2UIProvider.js.map +1 -0
- package/a2ui/dist/react/A2UIRenderer.d.ts +34 -0
- package/a2ui/dist/react/A2UIRenderer.js +161 -0
- package/a2ui/dist/react/A2UIRenderer.js.map +1 -0
- package/a2ui/dist/react/FormContext.d.ts +10 -0
- package/a2ui/dist/react/FormContext.js +12 -0
- package/a2ui/dist/react/FormContext.js.map +1 -0
- package/a2ui/dist/react/index.d.ts +8 -0
- package/a2ui/dist/react/index.js +23 -0
- package/a2ui/dist/react/index.js.map +1 -0
- package/a2ui/dist/react/useA2UIContext.d.ts +7 -0
- package/a2ui/dist/react/useA2UIContext.js +19 -0
- package/a2ui/dist/react/useA2UIContext.js.map +1 -0
- package/a2ui/dist/react/useAction.d.ts +9 -0
- package/a2ui/dist/react/useAction.js +38 -0
- package/a2ui/dist/react/useAction.js.map +1 -0
- package/a2ui/dist/react/useCatalog.d.ts +7 -0
- package/a2ui/dist/react/useCatalog.js +13 -0
- package/a2ui/dist/react/useCatalog.js.map +1 -0
- package/a2ui/dist/react/useChecks.d.ts +27 -0
- package/a2ui/dist/react/useChecks.js +76 -0
- package/a2ui/dist/react/useChecks.js.map +1 -0
- package/a2ui/dist/react/useDataBinding.d.ts +10 -0
- package/a2ui/dist/react/useDataBinding.js +175 -0
- package/a2ui/dist/react/useDataBinding.js.map +1 -0
- package/a2ui/dist/store/FormController.d.ts +23 -0
- package/a2ui/dist/store/FormController.js +40 -0
- package/a2ui/dist/store/FormController.js.map +1 -0
- package/a2ui/dist/store/FunctionRegistry.d.ts +47 -0
- package/a2ui/dist/store/FunctionRegistry.js +23 -0
- package/a2ui/dist/store/FunctionRegistry.js.map +1 -0
- package/a2ui/dist/store/MessageProcessor.d.ts +28 -0
- package/a2ui/dist/store/MessageProcessor.js +408 -0
- package/a2ui/dist/store/MessageProcessor.js.map +1 -0
- package/a2ui/dist/store/MessageStore.d.ts +38 -0
- package/a2ui/dist/store/MessageStore.js +37 -0
- package/a2ui/dist/store/MessageStore.js.map +1 -0
- package/a2ui/dist/store/Resource.d.ts +45 -0
- package/a2ui/dist/store/Resource.js +80 -0
- package/a2ui/dist/store/Resource.js.map +1 -0
- package/a2ui/dist/store/SignalStore.d.ts +10 -0
- package/a2ui/dist/store/SignalStore.js +29 -0
- package/a2ui/dist/store/SignalStore.js.map +1 -0
- package/a2ui/dist/store/index.d.ts +14 -0
- package/a2ui/dist/store/index.js +15 -0
- package/a2ui/dist/store/index.js.map +1 -0
- package/a2ui/dist/store/payloadNormalizer.d.ts +27 -0
- package/a2ui/dist/store/payloadNormalizer.js +179 -0
- package/a2ui/dist/store/payloadNormalizer.js.map +1 -0
- package/a2ui/dist/store/resolveFunctionCall.d.ts +18 -0
- package/a2ui/dist/store/resolveFunctionCall.js +131 -0
- package/a2ui/dist/store/resolveFunctionCall.js.map +1 -0
- package/a2ui/dist/store/types.d.ts +68 -0
- package/a2ui/dist/store/types.js +2 -0
- package/a2ui/dist/store/types.js.map +1 -0
- package/a2ui/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui/styles/catalog/Button.css +83 -0
- package/a2ui/styles/catalog/Card.css +49 -0
- package/a2ui/styles/catalog/CheckBox.css +46 -0
- package/a2ui/styles/catalog/Column.css +89 -0
- package/a2ui/styles/catalog/Divider.css +20 -0
- package/a2ui/styles/catalog/Icon.css +39 -0
- package/a2ui/styles/catalog/Image.css +54 -0
- package/a2ui/styles/catalog/LineChart.css +116 -0
- package/a2ui/styles/catalog/List.css +38 -0
- package/a2ui/styles/catalog/Modal.css +60 -0
- package/a2ui/styles/catalog/PieChart.css +109 -0
- package/a2ui/styles/catalog/RadioGroup.css +123 -0
- package/a2ui/styles/catalog/Row.css +83 -0
- package/a2ui/styles/catalog/Slider.css +96 -0
- package/a2ui/styles/catalog/Tabs.css +46 -0
- package/a2ui/styles/catalog/Text.css +121 -0
- package/a2ui/styles/catalog/TextField.css +48 -0
- package/a2ui/styles/theme.css +62 -0
- package/a2ui-catalog-extractor/README.md +605 -0
- package/a2ui-catalog-extractor/bin/a2ui-catalog-extractor.js +6 -0
- package/a2ui-catalog-extractor/dist/cli.d.ts +12 -0
- package/a2ui-catalog-extractor/dist/cli.js +171 -0
- package/a2ui-catalog-extractor/dist/cli.js.map +1 -0
- package/a2ui-catalog-extractor/dist/index.d.ts +140 -0
- package/a2ui-catalog-extractor/dist/index.js +755 -0
- package/a2ui-catalog-extractor/dist/index.js.map +1 -0
- package/a2ui-catalog-extractor/dist/tsconfig.build.tsbuildinfo +1 -0
- package/a2ui-catalog-extractor/skills/a2ui-catalog-extractor/SKILL.md +30 -0
- package/a2ui-prompt/README.md +65 -0
- package/a2ui-prompt/dist/index.d.ts +91 -0
- package/a2ui-prompt/dist/index.js +767 -0
- package/cli/README.md +88 -0
- package/cli/bin/cli.js +271 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/index.ts +114 -0
- package/openui/README.md +211 -0
- package/openui/dist/catalog/Action/index.d.ts +20 -0
- package/openui/dist/catalog/Action/index.js +23 -0
- package/openui/dist/catalog/Action/index.js.map +1 -0
- package/openui/dist/catalog/Button/index.d.ts +64 -0
- package/openui/dist/catalog/Button/index.js +75 -0
- package/openui/dist/catalog/Button/index.js.map +1 -0
- package/openui/dist/catalog/Card/index.d.ts +34 -0
- package/openui/dist/catalog/Card/index.js +69 -0
- package/openui/dist/catalog/Card/index.js.map +1 -0
- package/openui/dist/catalog/CardHeader/index.d.ts +5 -0
- package/openui/dist/catalog/CardHeader/index.js +18 -0
- package/openui/dist/catalog/CardHeader/index.js.map +1 -0
- package/openui/dist/catalog/Separator/index.d.ts +2 -0
- package/openui/dist/catalog/Separator/index.js +13 -0
- package/openui/dist/catalog/Separator/index.js.map +1 -0
- package/openui/dist/catalog/Stack/index.d.ts +29 -0
- package/openui/dist/catalog/Stack/index.js +61 -0
- package/openui/dist/catalog/Stack/index.js.map +1 -0
- package/openui/dist/catalog/Tag/index.d.ts +4 -0
- package/openui/dist/catalog/Tag/index.js +15 -0
- package/openui/dist/catalog/Tag/index.js.map +1 -0
- package/openui/dist/catalog/TextContent/index.d.ts +11 -0
- package/openui/dist/catalog/TextContent/index.js +33 -0
- package/openui/dist/catalog/TextContent/index.js.map +1 -0
- package/openui/dist/catalog/index.d.ts +7 -0
- package/openui/dist/catalog/index.js +11 -0
- package/openui/dist/catalog/index.js.map +1 -0
- package/openui/dist/catalog/utils.d.ts +2 -0
- package/openui/dist/catalog/utils.js +17 -0
- package/openui/dist/catalog/utils.js.map +1 -0
- package/openui/dist/core/context.d.ts +112 -0
- package/openui/dist/core/context.js +99 -0
- package/openui/dist/core/context.js.map +1 -0
- package/openui/dist/core/createLibrary.d.ts +10 -0
- package/openui/dist/core/createLibrary.js +36 -0
- package/openui/dist/core/createLibrary.js.map +1 -0
- package/openui/dist/core/hooks/index.d.ts +4 -0
- package/openui/dist/core/hooks/index.js +6 -0
- package/openui/dist/core/hooks/index.js.map +1 -0
- package/openui/dist/core/hooks/useFormValidation.d.ts +13 -0
- package/openui/dist/core/hooks/useFormValidation.js +76 -0
- package/openui/dist/core/hooks/useFormValidation.js.map +1 -0
- package/openui/dist/core/hooks/useOpenUIState.d.ts +33 -0
- package/openui/dist/core/hooks/useOpenUIState.js +413 -0
- package/openui/dist/core/hooks/useOpenUIState.js.map +1 -0
- package/openui/dist/core/hooks/useStateField.d.ts +2 -0
- package/openui/dist/core/hooks/useStateField.js +11 -0
- package/openui/dist/core/hooks/useStateField.js.map +1 -0
- package/openui/dist/core/index.d.ts +7 -0
- package/openui/dist/core/index.js +8 -0
- package/openui/dist/core/index.js.map +1 -0
- package/openui/dist/core/library.d.ts +20 -0
- package/openui/dist/core/library.js +13 -0
- package/openui/dist/core/library.js.map +1 -0
- package/openui/dist/core/renderer.css +271 -0
- package/openui/dist/core/renderer.d.ts +9 -0
- package/openui/dist/core/renderer.js +139 -0
- package/openui/dist/core/renderer.js.map +1 -0
- package/openui/dist/core/utils.d.ts +1 -0
- package/openui/dist/core/utils.js +76 -0
- package/openui/dist/core/utils.js.map +1 -0
- package/package.json +120 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
import { createResource } from './Resource.js';
|
|
2
|
+
import { SignalStore } from './SignalStore.js';
|
|
3
|
+
function isObject(value) {
|
|
4
|
+
return typeof value === 'object' && value !== null;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* `null` / `undefined` / empty array / empty object → `false`.
|
|
8
|
+
* Used by `dispatch()` to decide whether a listener's response should
|
|
9
|
+
* win over later responses from other listeners.
|
|
10
|
+
*/
|
|
11
|
+
function isMeaningfulResponse(value) {
|
|
12
|
+
if (value === null || value === undefined)
|
|
13
|
+
return false;
|
|
14
|
+
if (Array.isArray(value))
|
|
15
|
+
return value.length > 0;
|
|
16
|
+
if (typeof value === 'object') {
|
|
17
|
+
return Object.keys(value).length > 0;
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
export class MessageProcessor {
|
|
22
|
+
surfaces;
|
|
23
|
+
eventListeners = new Set();
|
|
24
|
+
updateListeners = new Set();
|
|
25
|
+
constructor() {
|
|
26
|
+
this.surfaces = new Map();
|
|
27
|
+
}
|
|
28
|
+
onUpdate(callback) {
|
|
29
|
+
this.updateListeners.add(callback);
|
|
30
|
+
return () => {
|
|
31
|
+
this.updateListeners.delete(callback);
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
emitUpdate(data) {
|
|
35
|
+
for (const cb of this.updateListeners)
|
|
36
|
+
cb(data);
|
|
37
|
+
}
|
|
38
|
+
dispatch(message) {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
if (this.eventListeners.size === 0) {
|
|
41
|
+
resolve([]);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Each listener gets its own one-shot resolver so multiple
|
|
45
|
+
// subscribers don't race on the shared outer `resolve` (which
|
|
46
|
+
// would let whoever calls it first decide the dispatch result and
|
|
47
|
+
// silently drop responses from the rest). We resolve with the
|
|
48
|
+
// first non-empty response, falling back to an empty array if
|
|
49
|
+
// every listener yielded nothing.
|
|
50
|
+
const total = this.eventListeners.size;
|
|
51
|
+
let settled = 0;
|
|
52
|
+
let firstResponse;
|
|
53
|
+
let hasResponse = false;
|
|
54
|
+
const tryResolve = () => {
|
|
55
|
+
settled += 1;
|
|
56
|
+
if (settled >= total) {
|
|
57
|
+
resolve(hasResponse ? firstResponse : []);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
for (const cb of this.eventListeners) {
|
|
61
|
+
let called = false;
|
|
62
|
+
cb({
|
|
63
|
+
message,
|
|
64
|
+
resolve: (value) => {
|
|
65
|
+
if (called)
|
|
66
|
+
return;
|
|
67
|
+
called = true;
|
|
68
|
+
// Only treat the first **meaningful** response as the result.
|
|
69
|
+
// Listeners that resolve `[]` / `null` / `{}` (the no-op
|
|
70
|
+
// pattern from `<A2UI>`'s internal listener) shouldn't
|
|
71
|
+
// shadow a real response from another subscriber.
|
|
72
|
+
if (!hasResponse && isMeaningfulResponse(value)) {
|
|
73
|
+
hasResponse = true;
|
|
74
|
+
firstResponse = value;
|
|
75
|
+
}
|
|
76
|
+
tryResolve();
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
onEvent(callback) {
|
|
83
|
+
this.eventListeners.add(callback);
|
|
84
|
+
return () => {
|
|
85
|
+
this.eventListeners.delete(callback);
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
getSurfaces() {
|
|
89
|
+
return this.surfaces;
|
|
90
|
+
}
|
|
91
|
+
clearSurfaces() {
|
|
92
|
+
this.surfaces.clear();
|
|
93
|
+
}
|
|
94
|
+
getOrCreateSurface(surfaceId) {
|
|
95
|
+
let surface = this.surfaces.get(surfaceId);
|
|
96
|
+
if (!surface) {
|
|
97
|
+
surface = {
|
|
98
|
+
surfaceId,
|
|
99
|
+
rootComponentId: null,
|
|
100
|
+
components: new Map(),
|
|
101
|
+
resources: new Map(),
|
|
102
|
+
store: new SignalStore(),
|
|
103
|
+
};
|
|
104
|
+
this.surfaces.set(surfaceId, surface);
|
|
105
|
+
}
|
|
106
|
+
else if (!surface.store) {
|
|
107
|
+
surface.store = new SignalStore();
|
|
108
|
+
}
|
|
109
|
+
return surface;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Resolve a JSON Pointer taking into account the current data context.
|
|
113
|
+
*
|
|
114
|
+
* - Absolute paths (starting with '/') are returned as-is.
|
|
115
|
+
* - Relative paths are resolved against the provided dataContextPath.
|
|
116
|
+
*/
|
|
117
|
+
resolvePath(path, dataContextPath) {
|
|
118
|
+
if (!path)
|
|
119
|
+
return path;
|
|
120
|
+
if (path.startsWith('/')) {
|
|
121
|
+
return path;
|
|
122
|
+
}
|
|
123
|
+
const context = dataContextPath ?? '';
|
|
124
|
+
const cleanContext = context.endsWith('/') ? context.slice(0, -1) : context;
|
|
125
|
+
if (path.startsWith('./')) {
|
|
126
|
+
const rest = path.substring(2);
|
|
127
|
+
if (!cleanContext) {
|
|
128
|
+
return `/${rest}`;
|
|
129
|
+
}
|
|
130
|
+
return `${cleanContext}/${rest}`;
|
|
131
|
+
}
|
|
132
|
+
if (!cleanContext) {
|
|
133
|
+
return `/${path}`;
|
|
134
|
+
}
|
|
135
|
+
return `${cleanContext}/${path}`;
|
|
136
|
+
}
|
|
137
|
+
cloneComponentTree(originalId, newIdSuffix, dataContextPath, surface, updates) {
|
|
138
|
+
const original = surface.components.get(originalId);
|
|
139
|
+
if (!original)
|
|
140
|
+
return null;
|
|
141
|
+
const newId = `${originalId}${newIdSuffix}`;
|
|
142
|
+
const cloned = JSON.parse(JSON.stringify(original));
|
|
143
|
+
cloned['id'] = newId;
|
|
144
|
+
cloned.dataContextPath = dataContextPath;
|
|
145
|
+
surface.components.set(newId, cloned);
|
|
146
|
+
updates.push(cloned);
|
|
147
|
+
if (!surface.resources.has(newId)) {
|
|
148
|
+
surface.resources.set(newId, createResource(newId));
|
|
149
|
+
}
|
|
150
|
+
const anyCloned = cloned;
|
|
151
|
+
const clonedRefs = new Map();
|
|
152
|
+
const cloneReference = (childId) => {
|
|
153
|
+
if (clonedRefs.has(childId))
|
|
154
|
+
return clonedRefs.get(childId) ?? null;
|
|
155
|
+
const newChildId = this.cloneComponentTree(childId, newIdSuffix, dataContextPath, surface, updates);
|
|
156
|
+
clonedRefs.set(childId, newChildId);
|
|
157
|
+
return newChildId;
|
|
158
|
+
};
|
|
159
|
+
const cloneStringField = (field) => {
|
|
160
|
+
const childId = anyCloned[field];
|
|
161
|
+
if (typeof childId !== 'string')
|
|
162
|
+
return;
|
|
163
|
+
const newChildId = cloneReference(childId);
|
|
164
|
+
if (newChildId) {
|
|
165
|
+
anyCloned[field] = newChildId;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
if (Array.isArray(anyCloned['children'])) {
|
|
169
|
+
const newChildren = [];
|
|
170
|
+
for (const childId of anyCloned['children']) {
|
|
171
|
+
if (typeof childId !== 'string')
|
|
172
|
+
continue;
|
|
173
|
+
const newChildId = cloneReference(childId);
|
|
174
|
+
if (newChildId)
|
|
175
|
+
newChildren.push(newChildId);
|
|
176
|
+
}
|
|
177
|
+
anyCloned['children'] = newChildren;
|
|
178
|
+
}
|
|
179
|
+
cloneStringField('child');
|
|
180
|
+
if (Array.isArray(anyCloned['tabs'])) {
|
|
181
|
+
anyCloned['tabs'] = anyCloned['tabs'].map((tab) => {
|
|
182
|
+
if (!tab || typeof tab !== 'object')
|
|
183
|
+
return tab;
|
|
184
|
+
const tabObject = tab;
|
|
185
|
+
const childId = tabObject['child'];
|
|
186
|
+
if (typeof childId !== 'string')
|
|
187
|
+
return tab;
|
|
188
|
+
const newChildId = cloneReference(childId);
|
|
189
|
+
if (!newChildId)
|
|
190
|
+
return tab;
|
|
191
|
+
return { ...tabObject, child: newChildId };
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
cloneStringField('trigger');
|
|
195
|
+
cloneStringField('content');
|
|
196
|
+
cloneStringField('entryPointChild');
|
|
197
|
+
cloneStringField('contentChild');
|
|
198
|
+
return newId;
|
|
199
|
+
}
|
|
200
|
+
flattenValue(value, basePath, updates) {
|
|
201
|
+
const normalizedBase = basePath === '' ? '/' : basePath;
|
|
202
|
+
const push = (path, v) => {
|
|
203
|
+
updates.push({ path, value: v });
|
|
204
|
+
};
|
|
205
|
+
if (Array.isArray(value)) {
|
|
206
|
+
push(normalizedBase, value);
|
|
207
|
+
value.forEach((item, index) => {
|
|
208
|
+
const childPath = normalizedBase === '/'
|
|
209
|
+
? `/${index}`
|
|
210
|
+
: `${normalizedBase}/${index}`;
|
|
211
|
+
if (isObject(item) || Array.isArray(item)) {
|
|
212
|
+
push(childPath, item);
|
|
213
|
+
this.flattenValue(item, childPath, updates);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
updates.push({ path: childPath, value: String(item) });
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (isObject(value)) {
|
|
222
|
+
push(normalizedBase, value);
|
|
223
|
+
for (const [key, v] of Object.entries(value)) {
|
|
224
|
+
const childPath = normalizedBase === '/'
|
|
225
|
+
? `/${key}`
|
|
226
|
+
: `${normalizedBase}/${key}`;
|
|
227
|
+
if (isObject(v) || Array.isArray(v)) {
|
|
228
|
+
push(childPath, v);
|
|
229
|
+
this.flattenValue(v, childPath, updates);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
updates.push({ path: childPath, value: String(v) });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
updates.push({ path: normalizedBase, value: String(value) });
|
|
238
|
+
}
|
|
239
|
+
processMessages(messages) {
|
|
240
|
+
for (const message of messages) {
|
|
241
|
+
if ('createSurface' in message && message.createSurface) {
|
|
242
|
+
const createSurface = message['createSurface'];
|
|
243
|
+
const surfaceId = createSurface['surfaceId'];
|
|
244
|
+
const surface = this.getOrCreateSurface(surfaceId);
|
|
245
|
+
const catId = createSurface['catalogId'];
|
|
246
|
+
if (catId !== undefined)
|
|
247
|
+
surface.catalogId = catId;
|
|
248
|
+
const t = createSurface['theme'];
|
|
249
|
+
if (t !== undefined) {
|
|
250
|
+
surface.theme = t;
|
|
251
|
+
}
|
|
252
|
+
const sData = createSurface['sendDataModel'];
|
|
253
|
+
if (sData !== undefined)
|
|
254
|
+
surface.sendDataModel = sData;
|
|
255
|
+
}
|
|
256
|
+
if ('updateComponents' in message && message.updateComponents) {
|
|
257
|
+
const { surfaceId, components } = message.updateComponents;
|
|
258
|
+
const surface = this.getOrCreateSurface(surfaceId);
|
|
259
|
+
const updatesMap = new Map();
|
|
260
|
+
for (const item of components) {
|
|
261
|
+
if (!item.id)
|
|
262
|
+
continue;
|
|
263
|
+
const existing = surface.components.get(item.id);
|
|
264
|
+
const dataContextPath = existing?.dataContextPath;
|
|
265
|
+
const instance = { ...item };
|
|
266
|
+
if (dataContextPath !== undefined) {
|
|
267
|
+
instance.dataContextPath = dataContextPath;
|
|
268
|
+
}
|
|
269
|
+
const anyInstance = instance;
|
|
270
|
+
if (anyInstance['children']
|
|
271
|
+
&& !Array.isArray(anyInstance['children'])
|
|
272
|
+
&& typeof anyInstance['children'] === 'object'
|
|
273
|
+
&& anyInstance['children'] !== null
|
|
274
|
+
&& typeof anyInstance['children']['componentId'] === 'string'
|
|
275
|
+
&& typeof anyInstance['children']['path'] === 'string') {
|
|
276
|
+
const templatePath = this.resolvePath(anyInstance['children']['path'], dataContextPath);
|
|
277
|
+
instance.__template = {
|
|
278
|
+
componentId: anyInstance['children']['componentId'],
|
|
279
|
+
path: templatePath,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
surface.components.set(instance.id, instance);
|
|
283
|
+
updatesMap.set(instance.id, instance);
|
|
284
|
+
if (!surface.resources.has(instance.id)) {
|
|
285
|
+
surface.resources.set(instance.id, createResource(instance.id));
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (!surface.rootComponentId) {
|
|
289
|
+
if (surface.components.has('root')) {
|
|
290
|
+
surface.rootComponentId = 'root';
|
|
291
|
+
}
|
|
292
|
+
else if (updatesMap.size > 0) {
|
|
293
|
+
surface.rootComponentId = updatesMap.keys().next().value ?? null;
|
|
294
|
+
}
|
|
295
|
+
if (surface.rootComponentId) {
|
|
296
|
+
if (!surface.resources.has(surface.rootComponentId)) {
|
|
297
|
+
surface.resources.set(surface.rootComponentId, createResource(surface.rootComponentId));
|
|
298
|
+
}
|
|
299
|
+
// Fall back to a surface-derived id so consumers that key
|
|
300
|
+
// resources by `messageId` still get a non-empty key when the
|
|
301
|
+
// protocol message lacks one (the v0.9 stream does not require
|
|
302
|
+
// `messageId` on every message).
|
|
303
|
+
const messageId = message.messageId
|
|
304
|
+
?? `surface:${surfaceId}`;
|
|
305
|
+
this.emitUpdate({
|
|
306
|
+
type: 'beginRendering',
|
|
307
|
+
surfaceId,
|
|
308
|
+
messageId,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const updates = Array.from(updatesMap.values());
|
|
313
|
+
if (updates.length > 0) {
|
|
314
|
+
this.emitUpdate({
|
|
315
|
+
type: 'surfaceUpdate',
|
|
316
|
+
updates,
|
|
317
|
+
surfaceId,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if ('updateDataModel' in message && message.updateDataModel) {
|
|
322
|
+
const { surfaceId, path, value } = message.updateDataModel;
|
|
323
|
+
const surface = this.getOrCreateSurface(surfaceId);
|
|
324
|
+
const updates = [];
|
|
325
|
+
if (value !== undefined) {
|
|
326
|
+
const basePath = path && path !== '' ? path : '/';
|
|
327
|
+
this.flattenValue(value, basePath, updates);
|
|
328
|
+
}
|
|
329
|
+
else if (path) {
|
|
330
|
+
updates.push({ path, value: '' });
|
|
331
|
+
}
|
|
332
|
+
if (updates.length > 0) {
|
|
333
|
+
surface.store.updateBatch(updates);
|
|
334
|
+
}
|
|
335
|
+
const componentUpdates = [];
|
|
336
|
+
for (const component of surface.components.values()) {
|
|
337
|
+
const anyComponent = component;
|
|
338
|
+
const templateInfo = anyComponent['__template'];
|
|
339
|
+
if (!templateInfo)
|
|
340
|
+
continue;
|
|
341
|
+
const dataSignal = surface.store.getSignal(templateInfo.path);
|
|
342
|
+
const rawData = dataSignal.value;
|
|
343
|
+
let data;
|
|
344
|
+
if (typeof rawData === 'string') {
|
|
345
|
+
try {
|
|
346
|
+
data = rawData ? JSON.parse(rawData) : undefined;
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
data = undefined;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
data = rawData;
|
|
354
|
+
}
|
|
355
|
+
const explicitChildren = [];
|
|
356
|
+
const generatedUpdates = [];
|
|
357
|
+
if (Array.isArray(data)) {
|
|
358
|
+
data.forEach((_, index) => {
|
|
359
|
+
const suffix = `:${index}`;
|
|
360
|
+
const ctx = `${templateInfo.path}/${index}`;
|
|
361
|
+
const newId = this.cloneComponentTree(templateInfo.componentId, suffix, ctx, surface, generatedUpdates);
|
|
362
|
+
if (newId) {
|
|
363
|
+
explicitChildren.push(newId);
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
else if (isObject(data)) {
|
|
368
|
+
for (const key of Object.keys(data)) {
|
|
369
|
+
const suffix = `:${key}`;
|
|
370
|
+
const ctx = `${templateInfo.path}/${key}`;
|
|
371
|
+
const newId = this.cloneComponentTree(templateInfo.componentId, suffix, ctx, surface, generatedUpdates);
|
|
372
|
+
if (newId) {
|
|
373
|
+
explicitChildren.push(newId);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
anyComponent['children'] = explicitChildren;
|
|
378
|
+
componentUpdates.push(component);
|
|
379
|
+
componentUpdates.push(...generatedUpdates);
|
|
380
|
+
}
|
|
381
|
+
if (componentUpdates.length > 0) {
|
|
382
|
+
this.emitUpdate({
|
|
383
|
+
type: 'surfaceUpdate',
|
|
384
|
+
updates: componentUpdates,
|
|
385
|
+
surfaceId,
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if ('deleteSurface' in message && message.deleteSurface) {
|
|
390
|
+
const { surfaceId } = message.deleteSurface;
|
|
391
|
+
const surface = this.surfaces.get(surfaceId);
|
|
392
|
+
// Same fallback as the synthesized `beginRendering` event so
|
|
393
|
+
// consumers that key lifecycle state by `messageId` always see
|
|
394
|
+
// a non-empty key when the protocol message lacks one.
|
|
395
|
+
const messageId = message.messageId
|
|
396
|
+
?? `surface:${surfaceId}`;
|
|
397
|
+
this.emitUpdate({
|
|
398
|
+
type: 'deleteSurface',
|
|
399
|
+
surfaceId,
|
|
400
|
+
targetId: surface?.rootComponentId ?? surfaceId,
|
|
401
|
+
messageId,
|
|
402
|
+
});
|
|
403
|
+
this.surfaces.delete(surfaceId);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=MessageProcessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageProcessor.js","sourceRoot":"","sources":["../../src/store/MessageProcessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ServerToClientMessage } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* A pure append-only buffer of raw protocol messages produced by the
|
|
4
|
+
* developer's IO module. The store knows nothing about the v0.9 protocol —
|
|
5
|
+
* it does not parse, process, or interpret messages. It only:
|
|
6
|
+
*
|
|
7
|
+
* 1. Stores them in arrival order.
|
|
8
|
+
* 2. Notifies subscribers when new ones land.
|
|
9
|
+
* 3. Hands the current snapshot back via `getSnapshot()` (referentially
|
|
10
|
+
* stable between mutations — required by `useSyncExternalStore`).
|
|
11
|
+
*
|
|
12
|
+
* Protocol-aware processing — surfaces, signals, resources, action
|
|
13
|
+
* dispatch — is the responsibility of `<A2UI>` (the renderer component).
|
|
14
|
+
* Developers who don't want to learn the protocol should use `<A2UI>`;
|
|
15
|
+
* developers who do can run their own `MessageProcessor` against the
|
|
16
|
+
* snapshot directly.
|
|
17
|
+
*/
|
|
18
|
+
export interface MessageStore {
|
|
19
|
+
/** `useSyncExternalStore` subscribe contract. */
|
|
20
|
+
readonly subscribe: (cb: () => void) => () => void;
|
|
21
|
+
/** `useSyncExternalStore` getSnapshot contract — stable between pushes. */
|
|
22
|
+
readonly getSnapshot: () => readonly ServerToClientMessage[];
|
|
23
|
+
/**
|
|
24
|
+
* Append one or more raw messages to the buffer. Notifies subscribers
|
|
25
|
+
* once per call (batches a single array argument into a single notify).
|
|
26
|
+
*/
|
|
27
|
+
push(message: ServerToClientMessage | readonly ServerToClientMessage[]): void;
|
|
28
|
+
/** Reset the buffer. Notifies subscribers. */
|
|
29
|
+
clear(): void;
|
|
30
|
+
}
|
|
31
|
+
export interface MessageStoreOptions {
|
|
32
|
+
/**
|
|
33
|
+
* Optional initial buffer contents. Useful when rehydrating a previous
|
|
34
|
+
* agent response or replaying a fixture stream.
|
|
35
|
+
*/
|
|
36
|
+
initialMessages?: readonly ServerToClientMessage[];
|
|
37
|
+
}
|
|
38
|
+
export declare function createMessageStore(options?: MessageStoreOptions): MessageStore;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export function createMessageStore(options = {}) {
|
|
2
|
+
let snapshot = options.initialMessages
|
|
3
|
+
? Object.freeze([...options.initialMessages])
|
|
4
|
+
: Object.freeze([]);
|
|
5
|
+
const subscribers = new Set();
|
|
6
|
+
const notify = () => {
|
|
7
|
+
for (const cb of subscribers)
|
|
8
|
+
cb();
|
|
9
|
+
};
|
|
10
|
+
return {
|
|
11
|
+
subscribe(cb) {
|
|
12
|
+
subscribers.add(cb);
|
|
13
|
+
return () => {
|
|
14
|
+
subscribers.delete(cb);
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
getSnapshot() {
|
|
18
|
+
return snapshot;
|
|
19
|
+
},
|
|
20
|
+
push(message) {
|
|
21
|
+
const incoming = Array.isArray(message)
|
|
22
|
+
? message
|
|
23
|
+
: [message];
|
|
24
|
+
if (incoming.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
snapshot = Object.freeze([...snapshot, ...incoming]);
|
|
27
|
+
notify();
|
|
28
|
+
},
|
|
29
|
+
clear() {
|
|
30
|
+
if (snapshot.length === 0)
|
|
31
|
+
return;
|
|
32
|
+
snapshot = Object.freeze([]);
|
|
33
|
+
notify();
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=MessageStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageStore.js","sourceRoot":"","sources":["../../src/store/MessageStore.ts"],"names":[],"mappings":"AA6CA,MAAM,UAAU,kBAAkB,CAChC,UAA+B,EAAE;IAEjC,IAAI,QAAQ,GAAqC,OAAO,CAAC,eAAe;QACtE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7C,CAAC,CAAC,MAAM,CAAC,MAAM,CAA0B,EAAE,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAc,CAAC;IAE1C,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,KAAK,MAAM,EAAE,IAAI,WAAW;YAAE,EAAE,EAAE,CAAC;IACrC,CAAC,CAAC;IAEF,OAAO;QACL,SAAS,CAAC,EAAE;YACV,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACpB,OAAO,GAAG,EAAE;gBACV,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC,CAAC;QACJ,CAAC;QACD,WAAW;YACT,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,CAAC,OAAO;YACV,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;gBACrC,CAAC,CAAE,OAAmC;gBACtC,CAAC,CAAC,CAAC,OAAgC,CAAC,CAAC;YACvC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAClC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;YACrD,MAAM,EAAE,CAAC;QACX,CAAC;QACD,KAAK;YACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO;YAClC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAA0B,EAAE,CAAC,CAAC;YACtD,MAAM,EAAE,CAAC;QACX,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type ResourceStatus = 'pending' | 'success' | 'error';
|
|
2
|
+
/**
|
|
3
|
+
* Immutable, transition-keyed snapshot returned by
|
|
4
|
+
* {@link Resource.getSnapshot}. The object reference changes on every
|
|
5
|
+
* `complete()` / `fail()` call so `useSyncExternalStore` re-renders even
|
|
6
|
+
* for `pending → error` transitions where `value` stays `undefined`.
|
|
7
|
+
*/
|
|
8
|
+
export interface ResourceSnapshot<T = unknown> {
|
|
9
|
+
status: ResourceStatus;
|
|
10
|
+
value: T | undefined;
|
|
11
|
+
error: unknown;
|
|
12
|
+
}
|
|
13
|
+
export interface Resource<T = unknown> {
|
|
14
|
+
id: string;
|
|
15
|
+
readonly completed: boolean;
|
|
16
|
+
readonly status: ResourceStatus;
|
|
17
|
+
readonly value: T | undefined;
|
|
18
|
+
readonly error: unknown;
|
|
19
|
+
/**
|
|
20
|
+
* @deprecated Read `value` / `status` directly. Retained for backwards
|
|
21
|
+
* compatibility; in the success state it returns the value, otherwise it
|
|
22
|
+
* returns undefined. It does not throw.
|
|
23
|
+
*/
|
|
24
|
+
read: () => T | undefined;
|
|
25
|
+
complete: (result: T) => void;
|
|
26
|
+
fail: (err: unknown) => void;
|
|
27
|
+
/**
|
|
28
|
+
* @deprecated Use `subscribe`. Behaves identically.
|
|
29
|
+
*/
|
|
30
|
+
onUpdate: (callback: (result: T) => void) => () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Subscribe to state changes. The callback is invoked after every
|
|
33
|
+
* `complete()` or `fail()` (the same value may be re-published when the
|
|
34
|
+
* processor re-emits an update for the same id). Returns a disposer.
|
|
35
|
+
*/
|
|
36
|
+
subscribe: (callback: () => void) => () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Synchronous read of the current snapshot, suitable for
|
|
39
|
+
* `useSyncExternalStore`. The returned object reference changes on every
|
|
40
|
+
* transition.
|
|
41
|
+
*/
|
|
42
|
+
getSnapshot: () => ResourceSnapshot<T>;
|
|
43
|
+
promise: Promise<T>;
|
|
44
|
+
}
|
|
45
|
+
export declare function createResource<T = unknown>(id: string): Resource<T>;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export function createResource(id) {
|
|
2
|
+
let resolve;
|
|
3
|
+
let reject;
|
|
4
|
+
const promise = new Promise((res, rej) => {
|
|
5
|
+
resolve = res;
|
|
6
|
+
reject = rej;
|
|
7
|
+
});
|
|
8
|
+
// Swallow unhandled rejection — listeners may attach later.
|
|
9
|
+
promise.catch(() => {
|
|
10
|
+
/* deferred: callers attach via subscribe / onUpdate */
|
|
11
|
+
});
|
|
12
|
+
let status = 'pending';
|
|
13
|
+
let value;
|
|
14
|
+
let error;
|
|
15
|
+
// Snapshot object whose reference changes on every transition so that
|
|
16
|
+
// `useSyncExternalStore`'s `Object.is` bail-out doesn't miss
|
|
17
|
+
// `pending → error` (where `value` stays `undefined`).
|
|
18
|
+
let snapshot = { status, value, error };
|
|
19
|
+
const listeners = new Set();
|
|
20
|
+
const notify = () => {
|
|
21
|
+
snapshot = { status, value, error };
|
|
22
|
+
for (const fn of listeners)
|
|
23
|
+
fn();
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
id,
|
|
27
|
+
promise,
|
|
28
|
+
get completed() {
|
|
29
|
+
return status === 'success';
|
|
30
|
+
},
|
|
31
|
+
get status() {
|
|
32
|
+
return status;
|
|
33
|
+
},
|
|
34
|
+
get value() {
|
|
35
|
+
return value;
|
|
36
|
+
},
|
|
37
|
+
get error() {
|
|
38
|
+
return error;
|
|
39
|
+
},
|
|
40
|
+
read: () => value,
|
|
41
|
+
complete: (res) => {
|
|
42
|
+
// `error` is terminal — refuse error → success transitions so
|
|
43
|
+
// observers don't see `{ status: 'success', error: <stale> }`.
|
|
44
|
+
if (status === 'error')
|
|
45
|
+
return;
|
|
46
|
+
const wasPending = status === 'pending';
|
|
47
|
+
value = res;
|
|
48
|
+
status = 'success';
|
|
49
|
+
if (wasPending)
|
|
50
|
+
resolve(res);
|
|
51
|
+
notify();
|
|
52
|
+
},
|
|
53
|
+
fail: (err) => {
|
|
54
|
+
if (status !== 'pending')
|
|
55
|
+
return;
|
|
56
|
+
error = err;
|
|
57
|
+
status = 'error';
|
|
58
|
+
reject(err);
|
|
59
|
+
notify();
|
|
60
|
+
},
|
|
61
|
+
onUpdate: (fn) => {
|
|
62
|
+
const wrapped = () => {
|
|
63
|
+
if (value !== undefined)
|
|
64
|
+
fn(value);
|
|
65
|
+
};
|
|
66
|
+
listeners.add(wrapped);
|
|
67
|
+
return () => {
|
|
68
|
+
listeners.delete(wrapped);
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
subscribe: (fn) => {
|
|
72
|
+
listeners.add(fn);
|
|
73
|
+
return () => {
|
|
74
|
+
listeners.delete(fn);
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
getSnapshot: () => snapshot,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=Resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Resource.js","sourceRoot":"","sources":["../../src/store/Resource.ts"],"names":[],"mappings":"AAkDA,MAAM,UAAU,cAAc,CAAc,EAAU;IACpD,IAAI,OAA4B,CAAC;IACjC,IAAI,MAA+B,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC1C,OAAO,GAAG,GAAG,CAAC;QACd,MAAM,GAAG,GAAG,CAAC;IACf,CAAC,CAAC,CAAC;IACH,4DAA4D;IAC5D,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;QACjB,uDAAuD;IACzD,CAAC,CAAC,CAAC;IAEH,IAAI,MAAM,GAAmB,SAAS,CAAC;IACvC,IAAI,KAAoB,CAAC;IACzB,IAAI,KAAc,CAAC;IACnB,sEAAsE;IACtE,6DAA6D;IAC7D,uDAAuD;IACvD,IAAI,QAAQ,GAAwB,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IAExC,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,QAAQ,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACpC,KAAK,MAAM,EAAE,IAAI,SAAS;YAAE,EAAE,EAAE,CAAC;IACnC,CAAC,CAAC;IAEF,OAAO;QACL,EAAE;QACF,OAAO;QACP,IAAI,SAAS;YACX,OAAO,MAAM,KAAK,SAAS,CAAC;QAC9B,CAAC;QACD,IAAI,MAAM;YACR,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,KAAK;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAK;YACP,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK;QACjB,QAAQ,EAAE,CAAC,GAAM,EAAE,EAAE;YACnB,8DAA8D;YAC9D,+DAA+D;YAC/D,IAAI,MAAM,KAAK,OAAO;gBAAE,OAAO;YAC/B,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC;YACxC,KAAK,GAAG,GAAG,CAAC;YACZ,MAAM,GAAG,SAAS,CAAC;YACnB,IAAI,UAAU;gBAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,EAAE,CAAC;QACX,CAAC;QACD,IAAI,EAAE,CAAC,GAAY,EAAE,EAAE;YACrB,IAAI,MAAM,KAAK,SAAS;gBAAE,OAAO;YACjC,KAAK,GAAG,GAAG,CAAC;YACZ,MAAM,GAAG,OAAO,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,CAAC;YACZ,MAAM,EAAE,CAAC;QACX,CAAC;QACD,QAAQ,EAAE,CAAC,EAAqB,EAAE,EAAE;YAClC,MAAM,OAAO,GAAG,GAAG,EAAE;gBACnB,IAAI,KAAK,KAAK,SAAS;oBAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YACrC,CAAC,CAAC;YACF,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAC5B,CAAC,CAAC;QACJ,CAAC;QACD,SAAS,EAAE,CAAC,EAAc,EAAE,EAAE;YAC5B,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClB,OAAO,GAAG,EAAE;gBACV,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvB,CAAC,CAAC;QACJ,CAAC;QACD,WAAW,EAAE,GAAG,EAAE,CAAC,QAAQ;KAC5B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Signal } from '@preact/signals';
|
|
2
|
+
export declare class SignalStore {
|
|
3
|
+
private signals;
|
|
4
|
+
getSignal(path: string, initialValue?: unknown): Signal<unknown>;
|
|
5
|
+
update(path: string, value: unknown): void;
|
|
6
|
+
updateBatch(updates: {
|
|
7
|
+
path: string;
|
|
8
|
+
value: unknown;
|
|
9
|
+
}[]): void;
|
|
10
|
+
}
|