@aigne/afs-ui 1.11.0-beta.12
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.md +26 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/aup-protocol.cjs +235 -0
- package/dist/aup-protocol.d.cts +78 -0
- package/dist/aup-protocol.d.cts.map +1 -0
- package/dist/aup-protocol.d.mts +78 -0
- package/dist/aup-protocol.d.mts.map +1 -0
- package/dist/aup-protocol.mjs +235 -0
- package/dist/aup-protocol.mjs.map +1 -0
- package/dist/aup-registry.cjs +2489 -0
- package/dist/aup-registry.mjs +2487 -0
- package/dist/aup-registry.mjs.map +1 -0
- package/dist/aup-spec.cjs +1467 -0
- package/dist/aup-spec.mjs +1466 -0
- package/dist/aup-spec.mjs.map +1 -0
- package/dist/aup-types.cjs +165 -0
- package/dist/aup-types.d.cts +157 -0
- package/dist/aup-types.d.cts.map +1 -0
- package/dist/aup-types.d.mts +157 -0
- package/dist/aup-types.d.mts.map +1 -0
- package/dist/aup-types.mjs +157 -0
- package/dist/aup-types.mjs.map +1 -0
- package/dist/backend.cjs +14 -0
- package/dist/backend.d.cts +104 -0
- package/dist/backend.d.cts.map +1 -0
- package/dist/backend.d.mts +104 -0
- package/dist/backend.d.mts.map +1 -0
- package/dist/backend.mjs +13 -0
- package/dist/backend.mjs.map +1 -0
- package/dist/degradation.cjs +85 -0
- package/dist/degradation.d.cts +17 -0
- package/dist/degradation.d.cts.map +1 -0
- package/dist/degradation.d.mts +17 -0
- package/dist/degradation.d.mts.map +1 -0
- package/dist/degradation.mjs +84 -0
- package/dist/degradation.mjs.map +1 -0
- package/dist/index.cjs +36 -0
- package/dist/index.d.cts +12 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +13 -0
- package/dist/runtime.cjs +117 -0
- package/dist/runtime.d.cts +59 -0
- package/dist/runtime.d.cts.map +1 -0
- package/dist/runtime.d.mts +59 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +118 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/session.cjs +159 -0
- package/dist/session.d.cts +80 -0
- package/dist/session.d.cts.map +1 -0
- package/dist/session.d.mts +80 -0
- package/dist/session.d.mts.map +1 -0
- package/dist/session.mjs +159 -0
- package/dist/session.mjs.map +1 -0
- package/dist/snapshot.cjs +162 -0
- package/dist/snapshot.mjs +163 -0
- package/dist/snapshot.mjs.map +1 -0
- package/dist/term-page.cjs +264 -0
- package/dist/term-page.mjs +264 -0
- package/dist/term-page.mjs.map +1 -0
- package/dist/term.cjs +295 -0
- package/dist/term.d.cts +84 -0
- package/dist/term.d.cts.map +1 -0
- package/dist/term.d.mts +84 -0
- package/dist/term.d.mts.map +1 -0
- package/dist/term.mjs +296 -0
- package/dist/term.mjs.map +1 -0
- package/dist/tty.cjs +136 -0
- package/dist/tty.d.cts +53 -0
- package/dist/tty.d.cts.map +1 -0
- package/dist/tty.d.mts +53 -0
- package/dist/tty.d.mts.map +1 -0
- package/dist/tty.mjs +135 -0
- package/dist/tty.mjs.map +1 -0
- package/dist/ui-provider.cjs +4615 -0
- package/dist/ui-provider.d.cts +307 -0
- package/dist/ui-provider.d.cts.map +1 -0
- package/dist/ui-provider.d.mts +307 -0
- package/dist/ui-provider.d.mts.map +1 -0
- package/dist/ui-provider.mjs +4616 -0
- package/dist/ui-provider.mjs.map +1 -0
- package/dist/web-page/core.cjs +1388 -0
- package/dist/web-page/core.mjs +1387 -0
- package/dist/web-page/core.mjs.map +1 -0
- package/dist/web-page/css.cjs +1699 -0
- package/dist/web-page/css.mjs +1698 -0
- package/dist/web-page/css.mjs.map +1 -0
- package/dist/web-page/icons.cjs +248 -0
- package/dist/web-page/icons.mjs +248 -0
- package/dist/web-page/icons.mjs.map +1 -0
- package/dist/web-page/overlay-themes.cjs +514 -0
- package/dist/web-page/overlay-themes.mjs +513 -0
- package/dist/web-page/overlay-themes.mjs.map +1 -0
- package/dist/web-page/renderers/action.cjs +72 -0
- package/dist/web-page/renderers/action.mjs +72 -0
- package/dist/web-page/renderers/action.mjs.map +1 -0
- package/dist/web-page/renderers/broadcast.cjs +160 -0
- package/dist/web-page/renderers/broadcast.mjs +160 -0
- package/dist/web-page/renderers/broadcast.mjs.map +1 -0
- package/dist/web-page/renderers/calendar.cjs +137 -0
- package/dist/web-page/renderers/calendar.mjs +137 -0
- package/dist/web-page/renderers/calendar.mjs.map +1 -0
- package/dist/web-page/renderers/canvas.cjs +173 -0
- package/dist/web-page/renderers/canvas.mjs +173 -0
- package/dist/web-page/renderers/canvas.mjs.map +1 -0
- package/dist/web-page/renderers/cdn-loader.cjs +25 -0
- package/dist/web-page/renderers/cdn-loader.mjs +25 -0
- package/dist/web-page/renderers/cdn-loader.mjs.map +1 -0
- package/dist/web-page/renderers/chart.cjs +101 -0
- package/dist/web-page/renderers/chart.mjs +101 -0
- package/dist/web-page/renderers/chart.mjs.map +1 -0
- package/dist/web-page/renderers/deck.cjs +390 -0
- package/dist/web-page/renderers/deck.mjs +390 -0
- package/dist/web-page/renderers/deck.mjs.map +1 -0
- package/dist/web-page/renderers/device.cjs +1015 -0
- package/dist/web-page/renderers/device.mjs +1015 -0
- package/dist/web-page/renderers/device.mjs.map +1 -0
- package/dist/web-page/renderers/editor.cjs +127 -0
- package/dist/web-page/renderers/editor.mjs +127 -0
- package/dist/web-page/renderers/editor.mjs.map +1 -0
- package/dist/web-page/renderers/finance-chart.cjs +178 -0
- package/dist/web-page/renderers/finance-chart.mjs +178 -0
- package/dist/web-page/renderers/finance-chart.mjs.map +1 -0
- package/dist/web-page/renderers/frame.cjs +274 -0
- package/dist/web-page/renderers/frame.mjs +274 -0
- package/dist/web-page/renderers/frame.mjs.map +1 -0
- package/dist/web-page/renderers/globe.cjs +119 -0
- package/dist/web-page/renderers/globe.mjs +119 -0
- package/dist/web-page/renderers/globe.mjs.map +1 -0
- package/dist/web-page/renderers/input.cjs +137 -0
- package/dist/web-page/renderers/input.mjs +137 -0
- package/dist/web-page/renderers/input.mjs.map +1 -0
- package/dist/web-page/renderers/list.cjs +1243 -0
- package/dist/web-page/renderers/list.mjs +1243 -0
- package/dist/web-page/renderers/list.mjs.map +1 -0
- package/dist/web-page/renderers/map.cjs +126 -0
- package/dist/web-page/renderers/map.mjs +126 -0
- package/dist/web-page/renderers/map.mjs.map +1 -0
- package/dist/web-page/renderers/media.cjs +106 -0
- package/dist/web-page/renderers/media.mjs +106 -0
- package/dist/web-page/renderers/media.mjs.map +1 -0
- package/dist/web-page/renderers/moonphase.cjs +105 -0
- package/dist/web-page/renderers/moonphase.mjs +105 -0
- package/dist/web-page/renderers/moonphase.mjs.map +1 -0
- package/dist/web-page/renderers/natal-chart.cjs +222 -0
- package/dist/web-page/renderers/natal-chart.mjs +222 -0
- package/dist/web-page/renderers/natal-chart.mjs.map +1 -0
- package/dist/web-page/renderers/overlay.cjs +531 -0
- package/dist/web-page/renderers/overlay.mjs +531 -0
- package/dist/web-page/renderers/overlay.mjs.map +1 -0
- package/dist/web-page/renderers/table.cjs +74 -0
- package/dist/web-page/renderers/table.mjs +74 -0
- package/dist/web-page/renderers/table.mjs.map +1 -0
- package/dist/web-page/renderers/terminal.cjs +30 -0
- package/dist/web-page/renderers/terminal.mjs +30 -0
- package/dist/web-page/renderers/terminal.mjs.map +1 -0
- package/dist/web-page/renderers/text.cjs +109 -0
- package/dist/web-page/renderers/text.mjs +109 -0
- package/dist/web-page/renderers/text.mjs.map +1 -0
- package/dist/web-page/renderers/ticker.cjs +133 -0
- package/dist/web-page/renderers/ticker.mjs +133 -0
- package/dist/web-page/renderers/ticker.mjs.map +1 -0
- package/dist/web-page/renderers/time.cjs +69 -0
- package/dist/web-page/renderers/time.mjs +69 -0
- package/dist/web-page/renderers/time.mjs.map +1 -0
- package/dist/web-page/renderers/unknown.cjs +20 -0
- package/dist/web-page/renderers/unknown.mjs +20 -0
- package/dist/web-page/renderers/unknown.mjs.map +1 -0
- package/dist/web-page/renderers/view.cjs +161 -0
- package/dist/web-page/renderers/view.mjs +161 -0
- package/dist/web-page/renderers/view.mjs.map +1 -0
- package/dist/web-page/renderers/wm.cjs +669 -0
- package/dist/web-page/renderers/wm.mjs +669 -0
- package/dist/web-page/renderers/wm.mjs.map +1 -0
- package/dist/web-page/skeleton.cjs +103 -0
- package/dist/web-page/skeleton.mjs +103 -0
- package/dist/web-page/skeleton.mjs.map +1 -0
- package/dist/web-page.cjs +114 -0
- package/dist/web-page.d.cts +19 -0
- package/dist/web-page.d.cts.map +1 -0
- package/dist/web-page.d.mts +19 -0
- package/dist/web-page.d.mts.map +1 -0
- package/dist/web-page.mjs +115 -0
- package/dist/web-page.mjs.map +1 -0
- package/dist/web.cjs +827 -0
- package/dist/web.d.cts +144 -0
- package/dist/web.d.cts.map +1 -0
- package/dist/web.d.mts +144 -0
- package/dist/web.d.mts.map +1 -0
- package/dist/web.mjs +828 -0
- package/dist/web.mjs.map +1 -0
- package/dist/wm-state.cjs +172 -0
- package/dist/wm-state.mjs +171 -0
- package/dist/wm-state.mjs.map +1 -0
- package/package.json +59 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2025 ArcBlock, Inc. All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are proprietary
|
|
6
|
+
and confidential. Unauthorized copying, modification, distribution, or use of
|
|
7
|
+
this Software, via any medium, is strictly prohibited.
|
|
8
|
+
|
|
9
|
+
The Software is provided for internal use only within ArcBlock, Inc. and its
|
|
10
|
+
authorized affiliates.
|
|
11
|
+
|
|
12
|
+
## No License Granted
|
|
13
|
+
|
|
14
|
+
No license, express or implied, is granted to any party for any purpose.
|
|
15
|
+
All rights are reserved by ArcBlock, Inc.
|
|
16
|
+
|
|
17
|
+
## Public Artifact Distribution
|
|
18
|
+
|
|
19
|
+
Portions of this Software may be released publicly under separate open-source
|
|
20
|
+
licenses (such as MIT License) through designated public repositories. Such
|
|
21
|
+
public releases are governed by their respective licenses and do not affect
|
|
22
|
+
the proprietary nature of this repository.
|
|
23
|
+
|
|
24
|
+
## Contact
|
|
25
|
+
|
|
26
|
+
For licensing inquiries, contact: legal@arcblock.io
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
|
|
3
|
+
function __decorate(decorators, target, key, desc) {
|
|
4
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
exports.__decorate = __decorate;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region \0@oxc-project+runtime@0.108.0/helpers/decorate.js
|
|
2
|
+
function __decorate(decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { __decorate };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
const require_aup_types = require('./aup-types.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/aup-protocol.ts
|
|
4
|
+
var AUPNodeStore = class {
|
|
5
|
+
root = null;
|
|
6
|
+
/** Flat index: id → node + parent reference for O(1) lookup */
|
|
7
|
+
index = /* @__PURE__ */ new Map();
|
|
8
|
+
/** Monotonic version counter — increments on every render or patch. */
|
|
9
|
+
_version = 0;
|
|
10
|
+
/** Render options from the last aup_render call. */
|
|
11
|
+
_renderOptions = {};
|
|
12
|
+
/** Current tree version (monotonically increasing). */
|
|
13
|
+
get version() {
|
|
14
|
+
return this._version;
|
|
15
|
+
}
|
|
16
|
+
/** Last render options (fullPage, style, chrome, etc.). */
|
|
17
|
+
get renderOptions() {
|
|
18
|
+
return this._renderOptions;
|
|
19
|
+
}
|
|
20
|
+
/** Save render options alongside the tree. */
|
|
21
|
+
setRenderOptions(opts) {
|
|
22
|
+
this._renderOptions = opts;
|
|
23
|
+
}
|
|
24
|
+
/** Get the current root node (or null if no graph is active). */
|
|
25
|
+
getRoot() {
|
|
26
|
+
return this.root;
|
|
27
|
+
}
|
|
28
|
+
/** Find a node by id. */
|
|
29
|
+
findNode(id) {
|
|
30
|
+
return this.index.get(id)?.node;
|
|
31
|
+
}
|
|
32
|
+
/** Set the full node tree (replaces any existing graph). */
|
|
33
|
+
setRoot(root) {
|
|
34
|
+
const err = require_aup_types.validateNode(root);
|
|
35
|
+
if (err) throw new Error(`Invalid AUP node: ${err}`);
|
|
36
|
+
this.root = root;
|
|
37
|
+
this._version++;
|
|
38
|
+
this.rebuildIndex();
|
|
39
|
+
}
|
|
40
|
+
/** Clear the graph. */
|
|
41
|
+
clear() {
|
|
42
|
+
this.root = null;
|
|
43
|
+
this.index.clear();
|
|
44
|
+
this._version++;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Apply a batch of patch operations atomically.
|
|
48
|
+
* If any op fails validation, the entire batch is rejected.
|
|
49
|
+
*/
|
|
50
|
+
applyPatch(ops) {
|
|
51
|
+
if (!this.root) throw new Error("No active AUP graph — call aup_render first");
|
|
52
|
+
for (const op of ops) {
|
|
53
|
+
const err = require_aup_types.validatePatchOp(op);
|
|
54
|
+
if (err) throw new Error(`Invalid patch op: ${err}`);
|
|
55
|
+
}
|
|
56
|
+
const snapshot = JSON.parse(JSON.stringify(this.root));
|
|
57
|
+
const snapshotIndex = new Map(this.index);
|
|
58
|
+
try {
|
|
59
|
+
for (const op of ops) this.applyOneOp(op);
|
|
60
|
+
this._version++;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
this.root = snapshot;
|
|
63
|
+
this.index = snapshotIndex;
|
|
64
|
+
this.rebuildIndex();
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
applyOneOp(op) {
|
|
69
|
+
switch (op.op) {
|
|
70
|
+
case "create":
|
|
71
|
+
this.opCreate(op);
|
|
72
|
+
break;
|
|
73
|
+
case "update":
|
|
74
|
+
this.opUpdate(op);
|
|
75
|
+
break;
|
|
76
|
+
case "remove":
|
|
77
|
+
this.opRemove(op);
|
|
78
|
+
break;
|
|
79
|
+
case "reorder":
|
|
80
|
+
this.opReorder(op);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
opCreate(op) {
|
|
85
|
+
if (this.index.has(op.id)) throw new Error(`Node already exists: ${op.id}`);
|
|
86
|
+
const parentEntry = this.index.get(op.parentId);
|
|
87
|
+
if (!parentEntry) throw new Error(`Parent node not found: ${op.parentId}`);
|
|
88
|
+
const parent = parentEntry.node;
|
|
89
|
+
if (!parent.children) parent.children = [];
|
|
90
|
+
const node = {
|
|
91
|
+
...op.node,
|
|
92
|
+
id: op.id
|
|
93
|
+
};
|
|
94
|
+
const err = require_aup_types.validateNode(node);
|
|
95
|
+
if (err) throw new Error(`Invalid node in create: ${err}`);
|
|
96
|
+
if (op.index !== void 0) {
|
|
97
|
+
if (op.index < 0 || op.index > parent.children.length) throw new Error(`Index out of bounds: ${op.index}`);
|
|
98
|
+
parent.children.splice(op.index, 0, node);
|
|
99
|
+
} else parent.children.push(node);
|
|
100
|
+
this.indexNode(node, parent);
|
|
101
|
+
}
|
|
102
|
+
opUpdate(op) {
|
|
103
|
+
const entry = this.index.get(op.id);
|
|
104
|
+
if (!entry) throw new Error(`Node not found: ${op.id}`);
|
|
105
|
+
const node = entry.node;
|
|
106
|
+
if (op.props && Object.keys(op.props).length > 0) node.props = {
|
|
107
|
+
...node.props ?? {},
|
|
108
|
+
...op.props
|
|
109
|
+
};
|
|
110
|
+
if (op.state && Object.keys(op.state).length > 0) node.state = {
|
|
111
|
+
...node.state ?? {},
|
|
112
|
+
...op.state
|
|
113
|
+
};
|
|
114
|
+
if (op.events !== void 0) node.events = op.events;
|
|
115
|
+
}
|
|
116
|
+
opRemove(op) {
|
|
117
|
+
if (this.root && op.id === this.root.id) {
|
|
118
|
+
this.clear();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const entry = this.index.get(op.id);
|
|
122
|
+
if (!entry) throw new Error(`Node not found: ${op.id}`);
|
|
123
|
+
const parent = entry.parent;
|
|
124
|
+
if (!parent || !parent.children) throw new Error(`Cannot remove node: no parent`);
|
|
125
|
+
const idx = parent.children.findIndex((c) => c.id === op.id);
|
|
126
|
+
if (idx < 0) throw new Error(`Node not found in parent's children: ${op.id}`);
|
|
127
|
+
const [removed] = parent.children.splice(idx, 1);
|
|
128
|
+
this.unindexNode(removed);
|
|
129
|
+
}
|
|
130
|
+
opReorder(op) {
|
|
131
|
+
if (!this.index.get(op.id)) throw new Error(`Node not found: ${op.id}`);
|
|
132
|
+
const parentEntry = this.index.get(op.parentId);
|
|
133
|
+
if (!parentEntry) throw new Error(`Parent node not found: ${op.parentId}`);
|
|
134
|
+
const parent = parentEntry.node;
|
|
135
|
+
if (!parent.children) throw new Error(`Parent has no children`);
|
|
136
|
+
const currentIdx = parent.children.findIndex((c) => c.id === op.id);
|
|
137
|
+
if (currentIdx < 0) throw new Error(`Node not in specified parent: ${op.id}`);
|
|
138
|
+
if (op.index < 0 || op.index >= parent.children.length) throw new Error(`Reorder index out of bounds: ${op.index}`);
|
|
139
|
+
const [node] = parent.children.splice(currentIdx, 1);
|
|
140
|
+
parent.children.splice(op.index, 0, node);
|
|
141
|
+
}
|
|
142
|
+
rebuildIndex() {
|
|
143
|
+
this.index.clear();
|
|
144
|
+
if (this.root) this.indexNode(this.root, null);
|
|
145
|
+
}
|
|
146
|
+
indexNode(node, parent) {
|
|
147
|
+
this.index.set(node.id, {
|
|
148
|
+
node,
|
|
149
|
+
parent
|
|
150
|
+
});
|
|
151
|
+
if (node.children) for (const child of node.children) this.indexNode(child, node);
|
|
152
|
+
}
|
|
153
|
+
unindexNode(node) {
|
|
154
|
+
this.index.delete(node.id);
|
|
155
|
+
if (node.children) for (const child of node.children) this.unindexNode(child);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var AUPSceneManager = class {
|
|
159
|
+
scenes = /* @__PURE__ */ new Map();
|
|
160
|
+
accessOrder = [];
|
|
161
|
+
_activeSceneId = null;
|
|
162
|
+
maxScenes;
|
|
163
|
+
constructor(opts) {
|
|
164
|
+
this.maxScenes = opts?.maxScenes ?? 3;
|
|
165
|
+
}
|
|
166
|
+
get activeSceneId() {
|
|
167
|
+
return this._activeSceneId;
|
|
168
|
+
}
|
|
169
|
+
/** Stage a scene (pre-render). Creates or updates the scene's store. */
|
|
170
|
+
stage(sceneId, root, opts) {
|
|
171
|
+
let store = this.scenes.get(sceneId);
|
|
172
|
+
if (!store) {
|
|
173
|
+
store = new AUPNodeStore();
|
|
174
|
+
this.scenes.set(sceneId, store);
|
|
175
|
+
}
|
|
176
|
+
store.setRoot(root);
|
|
177
|
+
if (opts) store.setRenderOptions(opts);
|
|
178
|
+
this.touch(sceneId);
|
|
179
|
+
this.evictIfNeeded();
|
|
180
|
+
return store;
|
|
181
|
+
}
|
|
182
|
+
/** Take a staged scene live. */
|
|
183
|
+
take(sceneId) {
|
|
184
|
+
const store = this.scenes.get(sceneId);
|
|
185
|
+
if (!store) throw new Error(`Scene not found/not staged: ${sceneId}`);
|
|
186
|
+
this._activeSceneId = sceneId;
|
|
187
|
+
this.touch(sceneId);
|
|
188
|
+
return store;
|
|
189
|
+
}
|
|
190
|
+
/** Release a scene's resources. Cannot release the active scene. */
|
|
191
|
+
release(sceneId) {
|
|
192
|
+
if (this._activeSceneId === sceneId) throw new Error(`Cannot release active/live scene: ${sceneId}`);
|
|
193
|
+
this.scenes.delete(sceneId);
|
|
194
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== sceneId);
|
|
195
|
+
}
|
|
196
|
+
/** Get a scene's store by ID. */
|
|
197
|
+
getScene(sceneId) {
|
|
198
|
+
return this.scenes.get(sceneId);
|
|
199
|
+
}
|
|
200
|
+
/** Get the active (live) scene. */
|
|
201
|
+
getActiveScene() {
|
|
202
|
+
if (!this._activeSceneId) return null;
|
|
203
|
+
const store = this.scenes.get(this._activeSceneId);
|
|
204
|
+
if (!store) return null;
|
|
205
|
+
return {
|
|
206
|
+
sceneId: this._activeSceneId,
|
|
207
|
+
store
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Apply patches to a staged scene. */
|
|
211
|
+
applyPatch(sceneId, ops) {
|
|
212
|
+
const store = this.scenes.get(sceneId);
|
|
213
|
+
if (!store) throw new Error(`Scene not found: ${sceneId}`);
|
|
214
|
+
store.applyPatch(ops);
|
|
215
|
+
this.touch(sceneId);
|
|
216
|
+
}
|
|
217
|
+
/** Touch LRU — move sceneId to end (most recent). */
|
|
218
|
+
touch(sceneId) {
|
|
219
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== sceneId);
|
|
220
|
+
this.accessOrder.push(sceneId);
|
|
221
|
+
}
|
|
222
|
+
/** Evict oldest non-active scenes if over limit. */
|
|
223
|
+
evictIfNeeded() {
|
|
224
|
+
while (this.scenes.size > this.maxScenes) {
|
|
225
|
+
const victim = this.accessOrder.find((id) => id !== this._activeSceneId && this.scenes.has(id));
|
|
226
|
+
if (!victim) break;
|
|
227
|
+
this.scenes.delete(victim);
|
|
228
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== victim);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
//#endregion
|
|
234
|
+
exports.AUPNodeStore = AUPNodeStore;
|
|
235
|
+
exports.AUPSceneManager = AUPSceneManager;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { AUPNode, AUPPatchOp } from "./aup-types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/aup-protocol.d.ts
|
|
4
|
+
interface AUPRenderOptions {
|
|
5
|
+
fullPage?: boolean;
|
|
6
|
+
chrome?: boolean;
|
|
7
|
+
theme?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
locale?: string;
|
|
10
|
+
}
|
|
11
|
+
declare class AUPNodeStore {
|
|
12
|
+
private root;
|
|
13
|
+
/** Flat index: id → node + parent reference for O(1) lookup */
|
|
14
|
+
private index;
|
|
15
|
+
/** Monotonic version counter — increments on every render or patch. */
|
|
16
|
+
private _version;
|
|
17
|
+
/** Render options from the last aup_render call. */
|
|
18
|
+
private _renderOptions;
|
|
19
|
+
/** Current tree version (monotonically increasing). */
|
|
20
|
+
get version(): number;
|
|
21
|
+
/** Last render options (fullPage, style, chrome, etc.). */
|
|
22
|
+
get renderOptions(): AUPRenderOptions;
|
|
23
|
+
/** Save render options alongside the tree. */
|
|
24
|
+
setRenderOptions(opts: AUPRenderOptions): void;
|
|
25
|
+
/** Get the current root node (or null if no graph is active). */
|
|
26
|
+
getRoot(): AUPNode | null;
|
|
27
|
+
/** Find a node by id. */
|
|
28
|
+
findNode(id: string): AUPNode | undefined;
|
|
29
|
+
/** Set the full node tree (replaces any existing graph). */
|
|
30
|
+
setRoot(root: AUPNode): void;
|
|
31
|
+
/** Clear the graph. */
|
|
32
|
+
clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Apply a batch of patch operations atomically.
|
|
35
|
+
* If any op fails validation, the entire batch is rejected.
|
|
36
|
+
*/
|
|
37
|
+
applyPatch(ops: AUPPatchOp[]): void;
|
|
38
|
+
private applyOneOp;
|
|
39
|
+
private opCreate;
|
|
40
|
+
private opUpdate;
|
|
41
|
+
private opRemove;
|
|
42
|
+
private opReorder;
|
|
43
|
+
private rebuildIndex;
|
|
44
|
+
private indexNode;
|
|
45
|
+
private unindexNode;
|
|
46
|
+
}
|
|
47
|
+
declare class AUPSceneManager {
|
|
48
|
+
private scenes;
|
|
49
|
+
private accessOrder;
|
|
50
|
+
private _activeSceneId;
|
|
51
|
+
private maxScenes;
|
|
52
|
+
constructor(opts?: {
|
|
53
|
+
maxScenes?: number;
|
|
54
|
+
});
|
|
55
|
+
get activeSceneId(): string | null;
|
|
56
|
+
/** Stage a scene (pre-render). Creates or updates the scene's store. */
|
|
57
|
+
stage(sceneId: string, root: AUPNode, opts?: AUPRenderOptions): AUPNodeStore;
|
|
58
|
+
/** Take a staged scene live. */
|
|
59
|
+
take(sceneId: string): AUPNodeStore;
|
|
60
|
+
/** Release a scene's resources. Cannot release the active scene. */
|
|
61
|
+
release(sceneId: string): void;
|
|
62
|
+
/** Get a scene's store by ID. */
|
|
63
|
+
getScene(sceneId: string): AUPNodeStore | undefined;
|
|
64
|
+
/** Get the active (live) scene. */
|
|
65
|
+
getActiveScene(): {
|
|
66
|
+
sceneId: string;
|
|
67
|
+
store: AUPNodeStore;
|
|
68
|
+
} | null;
|
|
69
|
+
/** Apply patches to a staged scene. */
|
|
70
|
+
applyPatch(sceneId: string, ops: AUPPatchOp[]): void;
|
|
71
|
+
/** Touch LRU — move sceneId to end (most recent). */
|
|
72
|
+
private touch;
|
|
73
|
+
/** Evict oldest non-active scenes if over limit. */
|
|
74
|
+
private evictIfNeeded;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { AUPNodeStore, AUPSceneManager };
|
|
78
|
+
//# sourceMappingURL=aup-protocol.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aup-protocol.d.cts","names":[],"sources":["../src/aup-protocol.ts"],"mappings":";;;UAUiB,gBAAA;EACf,QAAA;EACA,MAAA;EACA,KAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,cAGW,YAAA;EAAA,QACH,IAAA;;UAEA,KAAA;EAiBe;EAAA,QAff,QAAA;EAyBc;EAAA,QAvBd,cAAA;EA+CQ;EAAA,IA5CZ,OAAA,CAAA;EA4CsB;EAAA,IAvCtB,aAAA,CAAA,GAAiB,gBAAA;EAZb;EAiBR,gBAAA,CAAiB,IAAA,EAAM,gBAAA;EAbf;EAkBR,OAAA,CAAA,GAAW,OAAA;EAVP;EAeJ,QAAA,CAAS,EAAA,WAAa,OAAA;EAVtB;EAeA,OAAA,CAAQ,IAAA,EAAM,OAAA;EAfG;EAwBjB,KAAA,CAAA;EAnBW;;;;EA6BX,UAAA,CAAW,GAAA,EAAK,UAAA;EAAA,QA6BR,UAAA;EAAA,QAiBA,QAAA;EAAA,QAyBA,QAAA;EAAA,QAqBA,QAAA;EAAA,QAsBA,SAAA;EAAA,QAsBA,YAAA;EAAA,QAOA,SAAA;EAAA,QASA,WAAA;AAAA;AAAA,cAYG,eAAA;EAAA,QACH,MAAA;EAAA,QACA,WAAA;EAAA,QACA,cAAA;EAAA,QACA,SAAA;cAEI,IAAA;IAAS,SAAA;EAAA;EAAA,IAIjB,aAAA,CAAA;;EAKJ,KAAA,CAAM,OAAA,UAAiB,IAAA,EAAM,OAAA,EAAS,IAAA,GAAO,gBAAA,GAAmB,YAAA;EAAnB;EAc7C,IAAA,CAAK,OAAA,WAAkB,YAAA;EAAA;EASvB,OAAA,CAAQ,OAAA;EAcoC;EAL5C,QAAA,CAAS,OAAA,WAAkB,YAAA;EAagB;EAR3C,cAAA,CAAA;IAAoB,OAAA;IAAiB,KAAA,EAAO,YAAA;EAAA;EAhDpC;EAwDR,UAAA,CAAW,OAAA,UAAiB,GAAA,EAAK,UAAA;EAtDZ;EAAA,QA8Db,KAAA;EA1DJ;EAAA,QAgEI,aAAA;AAAA"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { AUPNode, AUPPatchOp } from "./aup-types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/aup-protocol.d.ts
|
|
4
|
+
interface AUPRenderOptions {
|
|
5
|
+
fullPage?: boolean;
|
|
6
|
+
chrome?: boolean;
|
|
7
|
+
theme?: string;
|
|
8
|
+
style?: string;
|
|
9
|
+
locale?: string;
|
|
10
|
+
}
|
|
11
|
+
declare class AUPNodeStore {
|
|
12
|
+
private root;
|
|
13
|
+
/** Flat index: id → node + parent reference for O(1) lookup */
|
|
14
|
+
private index;
|
|
15
|
+
/** Monotonic version counter — increments on every render or patch. */
|
|
16
|
+
private _version;
|
|
17
|
+
/** Render options from the last aup_render call. */
|
|
18
|
+
private _renderOptions;
|
|
19
|
+
/** Current tree version (monotonically increasing). */
|
|
20
|
+
get version(): number;
|
|
21
|
+
/** Last render options (fullPage, style, chrome, etc.). */
|
|
22
|
+
get renderOptions(): AUPRenderOptions;
|
|
23
|
+
/** Save render options alongside the tree. */
|
|
24
|
+
setRenderOptions(opts: AUPRenderOptions): void;
|
|
25
|
+
/** Get the current root node (or null if no graph is active). */
|
|
26
|
+
getRoot(): AUPNode | null;
|
|
27
|
+
/** Find a node by id. */
|
|
28
|
+
findNode(id: string): AUPNode | undefined;
|
|
29
|
+
/** Set the full node tree (replaces any existing graph). */
|
|
30
|
+
setRoot(root: AUPNode): void;
|
|
31
|
+
/** Clear the graph. */
|
|
32
|
+
clear(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Apply a batch of patch operations atomically.
|
|
35
|
+
* If any op fails validation, the entire batch is rejected.
|
|
36
|
+
*/
|
|
37
|
+
applyPatch(ops: AUPPatchOp[]): void;
|
|
38
|
+
private applyOneOp;
|
|
39
|
+
private opCreate;
|
|
40
|
+
private opUpdate;
|
|
41
|
+
private opRemove;
|
|
42
|
+
private opReorder;
|
|
43
|
+
private rebuildIndex;
|
|
44
|
+
private indexNode;
|
|
45
|
+
private unindexNode;
|
|
46
|
+
}
|
|
47
|
+
declare class AUPSceneManager {
|
|
48
|
+
private scenes;
|
|
49
|
+
private accessOrder;
|
|
50
|
+
private _activeSceneId;
|
|
51
|
+
private maxScenes;
|
|
52
|
+
constructor(opts?: {
|
|
53
|
+
maxScenes?: number;
|
|
54
|
+
});
|
|
55
|
+
get activeSceneId(): string | null;
|
|
56
|
+
/** Stage a scene (pre-render). Creates or updates the scene's store. */
|
|
57
|
+
stage(sceneId: string, root: AUPNode, opts?: AUPRenderOptions): AUPNodeStore;
|
|
58
|
+
/** Take a staged scene live. */
|
|
59
|
+
take(sceneId: string): AUPNodeStore;
|
|
60
|
+
/** Release a scene's resources. Cannot release the active scene. */
|
|
61
|
+
release(sceneId: string): void;
|
|
62
|
+
/** Get a scene's store by ID. */
|
|
63
|
+
getScene(sceneId: string): AUPNodeStore | undefined;
|
|
64
|
+
/** Get the active (live) scene. */
|
|
65
|
+
getActiveScene(): {
|
|
66
|
+
sceneId: string;
|
|
67
|
+
store: AUPNodeStore;
|
|
68
|
+
} | null;
|
|
69
|
+
/** Apply patches to a staged scene. */
|
|
70
|
+
applyPatch(sceneId: string, ops: AUPPatchOp[]): void;
|
|
71
|
+
/** Touch LRU — move sceneId to end (most recent). */
|
|
72
|
+
private touch;
|
|
73
|
+
/** Evict oldest non-active scenes if over limit. */
|
|
74
|
+
private evictIfNeeded;
|
|
75
|
+
}
|
|
76
|
+
//#endregion
|
|
77
|
+
export { AUPNodeStore, AUPSceneManager };
|
|
78
|
+
//# sourceMappingURL=aup-protocol.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aup-protocol.d.mts","names":[],"sources":["../src/aup-protocol.ts"],"mappings":";;;UAUiB,gBAAA;EACf,QAAA;EACA,MAAA;EACA,KAAA;EACA,KAAA;EACA,MAAA;AAAA;AAAA,cAGW,YAAA;EAAA,QACH,IAAA;;UAEA,KAAA;EAiBe;EAAA,QAff,QAAA;EAyBc;EAAA,QAvBd,cAAA;EA+CQ;EAAA,IA5CZ,OAAA,CAAA;EA4CsB;EAAA,IAvCtB,aAAA,CAAA,GAAiB,gBAAA;EAZb;EAiBR,gBAAA,CAAiB,IAAA,EAAM,gBAAA;EAbf;EAkBR,OAAA,CAAA,GAAW,OAAA;EAVP;EAeJ,QAAA,CAAS,EAAA,WAAa,OAAA;EAVtB;EAeA,OAAA,CAAQ,IAAA,EAAM,OAAA;EAfG;EAwBjB,KAAA,CAAA;EAnBW;;;;EA6BX,UAAA,CAAW,GAAA,EAAK,UAAA;EAAA,QA6BR,UAAA;EAAA,QAiBA,QAAA;EAAA,QAyBA,QAAA;EAAA,QAqBA,QAAA;EAAA,QAsBA,SAAA;EAAA,QAsBA,YAAA;EAAA,QAOA,SAAA;EAAA,QASA,WAAA;AAAA;AAAA,cAYG,eAAA;EAAA,QACH,MAAA;EAAA,QACA,WAAA;EAAA,QACA,cAAA;EAAA,QACA,SAAA;cAEI,IAAA;IAAS,SAAA;EAAA;EAAA,IAIjB,aAAA,CAAA;;EAKJ,KAAA,CAAM,OAAA,UAAiB,IAAA,EAAM,OAAA,EAAS,IAAA,GAAO,gBAAA,GAAmB,YAAA;EAAnB;EAc7C,IAAA,CAAK,OAAA,WAAkB,YAAA;EAAA;EASvB,OAAA,CAAQ,OAAA;EAcoC;EAL5C,QAAA,CAAS,OAAA,WAAkB,YAAA;EAagB;EAR3C,cAAA,CAAA;IAAoB,OAAA;IAAiB,KAAA,EAAO,YAAA;EAAA;EAhDpC;EAwDR,UAAA,CAAW,OAAA,UAAiB,GAAA,EAAK,UAAA;EAtDZ;EAAA,QA8Db,KAAA;EA1DJ;EAAA,QAgEI,aAAA;AAAA"}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { validateNode, validatePatchOp } from "./aup-types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/aup-protocol.ts
|
|
4
|
+
var AUPNodeStore = class {
|
|
5
|
+
root = null;
|
|
6
|
+
/** Flat index: id → node + parent reference for O(1) lookup */
|
|
7
|
+
index = /* @__PURE__ */ new Map();
|
|
8
|
+
/** Monotonic version counter — increments on every render or patch. */
|
|
9
|
+
_version = 0;
|
|
10
|
+
/** Render options from the last aup_render call. */
|
|
11
|
+
_renderOptions = {};
|
|
12
|
+
/** Current tree version (monotonically increasing). */
|
|
13
|
+
get version() {
|
|
14
|
+
return this._version;
|
|
15
|
+
}
|
|
16
|
+
/** Last render options (fullPage, style, chrome, etc.). */
|
|
17
|
+
get renderOptions() {
|
|
18
|
+
return this._renderOptions;
|
|
19
|
+
}
|
|
20
|
+
/** Save render options alongside the tree. */
|
|
21
|
+
setRenderOptions(opts) {
|
|
22
|
+
this._renderOptions = opts;
|
|
23
|
+
}
|
|
24
|
+
/** Get the current root node (or null if no graph is active). */
|
|
25
|
+
getRoot() {
|
|
26
|
+
return this.root;
|
|
27
|
+
}
|
|
28
|
+
/** Find a node by id. */
|
|
29
|
+
findNode(id) {
|
|
30
|
+
return this.index.get(id)?.node;
|
|
31
|
+
}
|
|
32
|
+
/** Set the full node tree (replaces any existing graph). */
|
|
33
|
+
setRoot(root) {
|
|
34
|
+
const err = validateNode(root);
|
|
35
|
+
if (err) throw new Error(`Invalid AUP node: ${err}`);
|
|
36
|
+
this.root = root;
|
|
37
|
+
this._version++;
|
|
38
|
+
this.rebuildIndex();
|
|
39
|
+
}
|
|
40
|
+
/** Clear the graph. */
|
|
41
|
+
clear() {
|
|
42
|
+
this.root = null;
|
|
43
|
+
this.index.clear();
|
|
44
|
+
this._version++;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Apply a batch of patch operations atomically.
|
|
48
|
+
* If any op fails validation, the entire batch is rejected.
|
|
49
|
+
*/
|
|
50
|
+
applyPatch(ops) {
|
|
51
|
+
if (!this.root) throw new Error("No active AUP graph — call aup_render first");
|
|
52
|
+
for (const op of ops) {
|
|
53
|
+
const err = validatePatchOp(op);
|
|
54
|
+
if (err) throw new Error(`Invalid patch op: ${err}`);
|
|
55
|
+
}
|
|
56
|
+
const snapshot = JSON.parse(JSON.stringify(this.root));
|
|
57
|
+
const snapshotIndex = new Map(this.index);
|
|
58
|
+
try {
|
|
59
|
+
for (const op of ops) this.applyOneOp(op);
|
|
60
|
+
this._version++;
|
|
61
|
+
} catch (e) {
|
|
62
|
+
this.root = snapshot;
|
|
63
|
+
this.index = snapshotIndex;
|
|
64
|
+
this.rebuildIndex();
|
|
65
|
+
throw e;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
applyOneOp(op) {
|
|
69
|
+
switch (op.op) {
|
|
70
|
+
case "create":
|
|
71
|
+
this.opCreate(op);
|
|
72
|
+
break;
|
|
73
|
+
case "update":
|
|
74
|
+
this.opUpdate(op);
|
|
75
|
+
break;
|
|
76
|
+
case "remove":
|
|
77
|
+
this.opRemove(op);
|
|
78
|
+
break;
|
|
79
|
+
case "reorder":
|
|
80
|
+
this.opReorder(op);
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
opCreate(op) {
|
|
85
|
+
if (this.index.has(op.id)) throw new Error(`Node already exists: ${op.id}`);
|
|
86
|
+
const parentEntry = this.index.get(op.parentId);
|
|
87
|
+
if (!parentEntry) throw new Error(`Parent node not found: ${op.parentId}`);
|
|
88
|
+
const parent = parentEntry.node;
|
|
89
|
+
if (!parent.children) parent.children = [];
|
|
90
|
+
const node = {
|
|
91
|
+
...op.node,
|
|
92
|
+
id: op.id
|
|
93
|
+
};
|
|
94
|
+
const err = validateNode(node);
|
|
95
|
+
if (err) throw new Error(`Invalid node in create: ${err}`);
|
|
96
|
+
if (op.index !== void 0) {
|
|
97
|
+
if (op.index < 0 || op.index > parent.children.length) throw new Error(`Index out of bounds: ${op.index}`);
|
|
98
|
+
parent.children.splice(op.index, 0, node);
|
|
99
|
+
} else parent.children.push(node);
|
|
100
|
+
this.indexNode(node, parent);
|
|
101
|
+
}
|
|
102
|
+
opUpdate(op) {
|
|
103
|
+
const entry = this.index.get(op.id);
|
|
104
|
+
if (!entry) throw new Error(`Node not found: ${op.id}`);
|
|
105
|
+
const node = entry.node;
|
|
106
|
+
if (op.props && Object.keys(op.props).length > 0) node.props = {
|
|
107
|
+
...node.props ?? {},
|
|
108
|
+
...op.props
|
|
109
|
+
};
|
|
110
|
+
if (op.state && Object.keys(op.state).length > 0) node.state = {
|
|
111
|
+
...node.state ?? {},
|
|
112
|
+
...op.state
|
|
113
|
+
};
|
|
114
|
+
if (op.events !== void 0) node.events = op.events;
|
|
115
|
+
}
|
|
116
|
+
opRemove(op) {
|
|
117
|
+
if (this.root && op.id === this.root.id) {
|
|
118
|
+
this.clear();
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const entry = this.index.get(op.id);
|
|
122
|
+
if (!entry) throw new Error(`Node not found: ${op.id}`);
|
|
123
|
+
const parent = entry.parent;
|
|
124
|
+
if (!parent || !parent.children) throw new Error(`Cannot remove node: no parent`);
|
|
125
|
+
const idx = parent.children.findIndex((c) => c.id === op.id);
|
|
126
|
+
if (idx < 0) throw new Error(`Node not found in parent's children: ${op.id}`);
|
|
127
|
+
const [removed] = parent.children.splice(idx, 1);
|
|
128
|
+
this.unindexNode(removed);
|
|
129
|
+
}
|
|
130
|
+
opReorder(op) {
|
|
131
|
+
if (!this.index.get(op.id)) throw new Error(`Node not found: ${op.id}`);
|
|
132
|
+
const parentEntry = this.index.get(op.parentId);
|
|
133
|
+
if (!parentEntry) throw new Error(`Parent node not found: ${op.parentId}`);
|
|
134
|
+
const parent = parentEntry.node;
|
|
135
|
+
if (!parent.children) throw new Error(`Parent has no children`);
|
|
136
|
+
const currentIdx = parent.children.findIndex((c) => c.id === op.id);
|
|
137
|
+
if (currentIdx < 0) throw new Error(`Node not in specified parent: ${op.id}`);
|
|
138
|
+
if (op.index < 0 || op.index >= parent.children.length) throw new Error(`Reorder index out of bounds: ${op.index}`);
|
|
139
|
+
const [node] = parent.children.splice(currentIdx, 1);
|
|
140
|
+
parent.children.splice(op.index, 0, node);
|
|
141
|
+
}
|
|
142
|
+
rebuildIndex() {
|
|
143
|
+
this.index.clear();
|
|
144
|
+
if (this.root) this.indexNode(this.root, null);
|
|
145
|
+
}
|
|
146
|
+
indexNode(node, parent) {
|
|
147
|
+
this.index.set(node.id, {
|
|
148
|
+
node,
|
|
149
|
+
parent
|
|
150
|
+
});
|
|
151
|
+
if (node.children) for (const child of node.children) this.indexNode(child, node);
|
|
152
|
+
}
|
|
153
|
+
unindexNode(node) {
|
|
154
|
+
this.index.delete(node.id);
|
|
155
|
+
if (node.children) for (const child of node.children) this.unindexNode(child);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
var AUPSceneManager = class {
|
|
159
|
+
scenes = /* @__PURE__ */ new Map();
|
|
160
|
+
accessOrder = [];
|
|
161
|
+
_activeSceneId = null;
|
|
162
|
+
maxScenes;
|
|
163
|
+
constructor(opts) {
|
|
164
|
+
this.maxScenes = opts?.maxScenes ?? 3;
|
|
165
|
+
}
|
|
166
|
+
get activeSceneId() {
|
|
167
|
+
return this._activeSceneId;
|
|
168
|
+
}
|
|
169
|
+
/** Stage a scene (pre-render). Creates or updates the scene's store. */
|
|
170
|
+
stage(sceneId, root, opts) {
|
|
171
|
+
let store = this.scenes.get(sceneId);
|
|
172
|
+
if (!store) {
|
|
173
|
+
store = new AUPNodeStore();
|
|
174
|
+
this.scenes.set(sceneId, store);
|
|
175
|
+
}
|
|
176
|
+
store.setRoot(root);
|
|
177
|
+
if (opts) store.setRenderOptions(opts);
|
|
178
|
+
this.touch(sceneId);
|
|
179
|
+
this.evictIfNeeded();
|
|
180
|
+
return store;
|
|
181
|
+
}
|
|
182
|
+
/** Take a staged scene live. */
|
|
183
|
+
take(sceneId) {
|
|
184
|
+
const store = this.scenes.get(sceneId);
|
|
185
|
+
if (!store) throw new Error(`Scene not found/not staged: ${sceneId}`);
|
|
186
|
+
this._activeSceneId = sceneId;
|
|
187
|
+
this.touch(sceneId);
|
|
188
|
+
return store;
|
|
189
|
+
}
|
|
190
|
+
/** Release a scene's resources. Cannot release the active scene. */
|
|
191
|
+
release(sceneId) {
|
|
192
|
+
if (this._activeSceneId === sceneId) throw new Error(`Cannot release active/live scene: ${sceneId}`);
|
|
193
|
+
this.scenes.delete(sceneId);
|
|
194
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== sceneId);
|
|
195
|
+
}
|
|
196
|
+
/** Get a scene's store by ID. */
|
|
197
|
+
getScene(sceneId) {
|
|
198
|
+
return this.scenes.get(sceneId);
|
|
199
|
+
}
|
|
200
|
+
/** Get the active (live) scene. */
|
|
201
|
+
getActiveScene() {
|
|
202
|
+
if (!this._activeSceneId) return null;
|
|
203
|
+
const store = this.scenes.get(this._activeSceneId);
|
|
204
|
+
if (!store) return null;
|
|
205
|
+
return {
|
|
206
|
+
sceneId: this._activeSceneId,
|
|
207
|
+
store
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/** Apply patches to a staged scene. */
|
|
211
|
+
applyPatch(sceneId, ops) {
|
|
212
|
+
const store = this.scenes.get(sceneId);
|
|
213
|
+
if (!store) throw new Error(`Scene not found: ${sceneId}`);
|
|
214
|
+
store.applyPatch(ops);
|
|
215
|
+
this.touch(sceneId);
|
|
216
|
+
}
|
|
217
|
+
/** Touch LRU — move sceneId to end (most recent). */
|
|
218
|
+
touch(sceneId) {
|
|
219
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== sceneId);
|
|
220
|
+
this.accessOrder.push(sceneId);
|
|
221
|
+
}
|
|
222
|
+
/** Evict oldest non-active scenes if over limit. */
|
|
223
|
+
evictIfNeeded() {
|
|
224
|
+
while (this.scenes.size > this.maxScenes) {
|
|
225
|
+
const victim = this.accessOrder.find((id) => id !== this._activeSceneId && this.scenes.has(id));
|
|
226
|
+
if (!victim) break;
|
|
227
|
+
this.scenes.delete(victim);
|
|
228
|
+
this.accessOrder = this.accessOrder.filter((id) => id !== victim);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
//#endregion
|
|
234
|
+
export { AUPNodeStore, AUPSceneManager };
|
|
235
|
+
//# sourceMappingURL=aup-protocol.mjs.map
|