@uicast/core 0.0.2 → 0.0.5
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.
|
@@ -7,18 +7,18 @@ type SetOptions = {
|
|
|
7
7
|
default?: boolean;
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
|
-
* A scope: its fields as plain properties, plus
|
|
10
|
+
* A scope: its fields as plain properties, plus `$emitter` and `$set`. A write to a field emits it; a write inside
|
|
11
11
|
* a field's value changes plain data and emits nothing.
|
|
12
12
|
*
|
|
13
13
|
* @example
|
|
14
14
|
* const root: ReactiveProxy = createProxyScope();
|
|
15
|
-
* const off = root
|
|
15
|
+
* const off = root.$emitter.on("user", () => console.log(root.user));
|
|
16
16
|
*/
|
|
17
17
|
type ReactiveProxy<T extends object = Record<string, unknown>> = T & {
|
|
18
|
-
/** Field subscriptions, e.g. `scope
|
|
19
|
-
|
|
18
|
+
/** Field subscriptions, e.g. `scope.$emitter.on("user", handler)`, which returns the unsubscribe function. */
|
|
19
|
+
$emitter: Pick<Emitter, "on">;
|
|
20
20
|
/** Writes a field, like assignment. `{ default: true }` writes only while it is undefined (first writer wins). */
|
|
21
|
-
|
|
21
|
+
$set: (field: string, value: unknown, options?: SetOptions) => void;
|
|
22
22
|
};
|
|
23
23
|
declare const countEmits: (scope: ReactiveProxy) => number;
|
|
24
24
|
/**
|
|
@@ -31,7 +31,7 @@ declare const countEmits: (scope: ReactiveProxy) => number;
|
|
|
31
31
|
*
|
|
32
32
|
* @example
|
|
33
33
|
* userCtx.plan = "free"; // emits "plan"
|
|
34
|
-
* userCtx
|
|
34
|
+
* userCtx.$set("plan", "pro", { default: true }); // no-op: "plan" is set
|
|
35
35
|
*/
|
|
36
36
|
declare function createProxyScope<T extends object>(bag?: T): ReactiveProxy<T>;
|
|
37
37
|
type ForwardTarget = {
|
|
@@ -26,7 +26,7 @@ function createEmitter() {
|
|
|
26
26
|
}
|
|
27
27
|
const isObject = (value) => value !== null && typeof value === "object";
|
|
28
28
|
// Every scope's emitter is `createEmitter`'s, so the count is there.
|
|
29
|
-
const countEmits = (scope) => scope
|
|
29
|
+
const countEmits = (scope) => scope.$emitter.emits;
|
|
30
30
|
function assertField(field) {
|
|
31
31
|
if (PROTOTYPE_KEYS.has(field)) {
|
|
32
32
|
throw new EntryError(`Cannot set "${field}": it reaches the prototype chain.`, {
|
|
@@ -49,7 +49,7 @@ function assertField(field) {
|
|
|
49
49
|
*
|
|
50
50
|
* @example
|
|
51
51
|
* userCtx.plan = "free"; // emits "plan"
|
|
52
|
-
* userCtx
|
|
52
|
+
* userCtx.$set("plan", "pro", { default: true }); // no-op: "plan" is set
|
|
53
53
|
*/
|
|
54
54
|
function createProxyScope(bag = {}) {
|
|
55
55
|
const emitter = createEmitter();
|
|
@@ -66,9 +66,9 @@ function createProxyScope(bag = {}) {
|
|
|
66
66
|
};
|
|
67
67
|
return new Proxy(bag, {
|
|
68
68
|
get(target, prop, receiver) {
|
|
69
|
-
if (prop === "
|
|
69
|
+
if (prop === "$emitter")
|
|
70
70
|
return emitter;
|
|
71
|
-
if (prop === "
|
|
71
|
+
if (prop === "$set")
|
|
72
72
|
return write;
|
|
73
73
|
return Reflect.get(target, prop, receiver);
|
|
74
74
|
},
|
|
@@ -200,15 +200,15 @@ function createRowScope() {
|
|
|
200
200
|
}
|
|
201
201
|
for (const [scope, fields] of next)
|
|
202
202
|
for (const [name, replaced] of fields)
|
|
203
|
-
scope
|
|
203
|
+
scope.$set(name, replaced);
|
|
204
204
|
element = copy;
|
|
205
205
|
emitter.emit(field);
|
|
206
206
|
};
|
|
207
207
|
const proxy = new Proxy({}, {
|
|
208
208
|
get(_, prop) {
|
|
209
|
-
if (prop === "
|
|
209
|
+
if (prop === "$emitter")
|
|
210
210
|
return emitter;
|
|
211
|
-
if (prop === "
|
|
211
|
+
if (prop === "$set")
|
|
212
212
|
return write;
|
|
213
213
|
if (typeof prop !== "string")
|
|
214
214
|
return undefined;
|
|
@@ -260,11 +260,11 @@ function createRowState() {
|
|
|
260
260
|
if (ROW_FIELDS.has(field)) {
|
|
261
261
|
throw new EntryError(`Cannot set "${field}": the runtime owns it.`, { reason: "guardrail-violation" });
|
|
262
262
|
}
|
|
263
|
-
scope
|
|
263
|
+
scope.$set(field, value, options);
|
|
264
264
|
};
|
|
265
265
|
const proxy = new Proxy(scope, {
|
|
266
266
|
get(target, prop, receiver) {
|
|
267
|
-
if (prop === "
|
|
267
|
+
if (prop === "$set")
|
|
268
268
|
return write;
|
|
269
269
|
if (typeof prop === "string" && ROW_FIELDS.has(prop))
|
|
270
270
|
return runtime[prop];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uicast/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "The framework-agnostic engine of uicast, the expression-driven generative UI framework: entry format, guarded expressions (allow-list, not a sandbox), reactive scopes, and prompt builders.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Andrey Gubanov (https://github.com/finom)",
|
|
@@ -56,6 +56,6 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"@uicast/expr": "^0.0.
|
|
59
|
+
"@uicast/expr": "^0.0.5"
|
|
60
60
|
}
|
|
61
61
|
}
|