@kumwe/studio-core 0.1.0-alpha.3 → 0.1.0-alpha.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.
@@ -0,0 +1,47 @@
1
+ import type { BlueprintCommand, BlueprintDocument, StudioCommand, StudioConfiguration, StudioSessionMode } from '@kumwe/studio-protocol';
2
+ /**
3
+ * Every session mode, in stable sorted order. The permitted-command table is
4
+ * total over exactly this set.
5
+ */
6
+ export declare const STUDIO_SESSION_MODES: readonly StudioSessionMode[];
7
+ /** Every canonical command type addressable by the mode table. */
8
+ export type StudioCommandType = StudioCommand['type'];
9
+ /**
10
+ * The deterministic mode-to-permitted-command table: one immutable set per
11
+ * session mode, shared across calls, so UIs derive disabled affordances from
12
+ * the same source the session enforces. The table is type-level only; the
13
+ * hybrid entries additionally require every affected collection to stay
14
+ * inside a structural authoring region, which the session enforces per
15
+ * command target.
16
+ */
17
+ export declare function permittedCommandTypes(mode: StudioSessionMode): ReadonlySet<StudioCommandType>;
18
+ /**
19
+ * Flattens a configuration's editing mode, composite, and session state into
20
+ * the single session mode fixed at session creation: a read-only session
21
+ * state always flattens to `read-only`, the hybrid composite flattens to
22
+ * `hybrid`, and every other session keeps its authoring mode. The hybrid
23
+ * composite is invalid with Model mode, mirroring the configuration schema.
24
+ */
25
+ export declare function resolveSessionMode(configuration: Pick<StudioConfiguration, 'composite' | 'mode' | 'sessionState'>): StudioSessionMode;
26
+ /**
27
+ * Fails closed with the stable `mode-forbidden` code when the command type is
28
+ * outside the active mode's permitted set.
29
+ */
30
+ export declare function assertModePermitsCommandType(mode: StudioSessionMode, type: StudioCommandType): void;
31
+ /**
32
+ * Enforces the bounded-composition rule for one hybrid structure command:
33
+ * every collection the command inserts into, removes from, moves across, or
34
+ * reorders must be a named slot of a node whose authoring policy mode is
35
+ * `structural`; inserted block types must satisfy the structural node's
36
+ * `allowedBlocks` when declared; subtrees containing a `locked` node are
37
+ * never inserted, removed, moved, or duplicated; and document roots are
38
+ * never in bounds. Batch operations are evaluated sequentially against a
39
+ * trial state so later operations may compose nodes earlier operations
40
+ * introduced. A violation fails closed with `mode-forbidden`; a reference
41
+ * the gate cannot resolve is left for the reducer's canonical failure code.
42
+ *
43
+ * The passed document is consumed as trial scratch state and may be mutated;
44
+ * callers pass a clone.
45
+ */
46
+ export declare function assertHybridCommandInBounds(document: BlueprintDocument, command: BlueprintCommand): void;
47
+ //# sourceMappingURL=modes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modes.d.ts","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAChB,iBAAiB,EAIjB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAGhC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAM3D,CAAC;AAEH,kEAAkE;AAClE,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;AAoDtD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,iBAAiB,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAE7F;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC,GAC9E,iBAAiB,CAWnB;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,EACvB,IAAI,EAAE,iBAAiB,GACtB,IAAI,CAON;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAyCN"}
package/dist/modes.js ADDED
@@ -0,0 +1,266 @@
1
+ import { applyOperation, StudioCommandError } from './commands.js';
2
+ /**
3
+ * Every session mode, in stable sorted order. The permitted-command table is
4
+ * total over exactly this set.
5
+ */
6
+ export const STUDIO_SESSION_MODES = Object.freeze([
7
+ 'blueprint',
8
+ 'content',
9
+ 'hybrid',
10
+ 'model',
11
+ 'read-only',
12
+ ]);
13
+ const BLUEPRINT_STRUCTURE_COMMAND_TYPES = [
14
+ 'studio.command/apply-pattern',
15
+ 'studio.command/batch',
16
+ 'studio.command/duplicate-node',
17
+ 'studio.command/insert-node',
18
+ 'studio.command/move-node',
19
+ 'studio.command/remove-binding',
20
+ 'studio.command/remove-node',
21
+ 'studio.command/reorder-children',
22
+ 'studio.command/reset-inherited-property',
23
+ 'studio.command/restore-node',
24
+ 'studio.command/set-binding',
25
+ 'studio.command/set-property',
26
+ 'studio.command/set-size-role',
27
+ 'studio.command/unset-property',
28
+ 'studio.command/unset-size-role',
29
+ ];
30
+ /**
31
+ * The structure commands hybrid composition may dispatch when every affected
32
+ * collection stays inside a structural authoring region. Property, binding,
33
+ * size-role, inheritance-reset, and pattern commands remain Blueprint-mode
34
+ * vocabulary.
35
+ */
36
+ const HYBRID_STRUCTURE_OPERATION_TYPES = [
37
+ 'studio.command/duplicate-node',
38
+ 'studio.command/insert-node',
39
+ 'studio.command/move-node',
40
+ 'studio.command/remove-node',
41
+ 'studio.command/reorder-children',
42
+ 'studio.command/restore-node',
43
+ ];
44
+ const PERMITTED_COMMAND_TYPES = Object.freeze({
45
+ blueprint: immutableCommandTypeSet(BLUEPRINT_STRUCTURE_COMMAND_TYPES),
46
+ content: immutableCommandTypeSet(['studio.command/set-field-value']),
47
+ hybrid: immutableCommandTypeSet([
48
+ 'studio.command/batch',
49
+ ...HYBRID_STRUCTURE_OPERATION_TYPES,
50
+ 'studio.command/set-field-value',
51
+ ]),
52
+ model: immutableCommandTypeSet(['studio.command/add-model-field']),
53
+ 'read-only': immutableCommandTypeSet([]),
54
+ });
55
+ const HYBRID_BATCHABLE_OPERATION_TYPES = immutableCommandTypeSet(HYBRID_STRUCTURE_OPERATION_TYPES);
56
+ /**
57
+ * The deterministic mode-to-permitted-command table: one immutable set per
58
+ * session mode, shared across calls, so UIs derive disabled affordances from
59
+ * the same source the session enforces. The table is type-level only; the
60
+ * hybrid entries additionally require every affected collection to stay
61
+ * inside a structural authoring region, which the session enforces per
62
+ * command target.
63
+ */
64
+ export function permittedCommandTypes(mode) {
65
+ return PERMITTED_COMMAND_TYPES[mode];
66
+ }
67
+ /**
68
+ * Flattens a configuration's editing mode, composite, and session state into
69
+ * the single session mode fixed at session creation: a read-only session
70
+ * state always flattens to `read-only`, the hybrid composite flattens to
71
+ * `hybrid`, and every other session keeps its authoring mode. The hybrid
72
+ * composite is invalid with Model mode, mirroring the configuration schema.
73
+ */
74
+ export function resolveSessionMode(configuration) {
75
+ if (configuration.sessionState === 'read-only') {
76
+ return 'read-only';
77
+ }
78
+ if (configuration.composite === 'hybrid') {
79
+ if (configuration.mode === 'model') {
80
+ throw new RangeError('The hybrid composite is invalid with the model editing mode.');
81
+ }
82
+ return 'hybrid';
83
+ }
84
+ return configuration.mode;
85
+ }
86
+ /**
87
+ * Fails closed with the stable `mode-forbidden` code when the command type is
88
+ * outside the active mode's permitted set.
89
+ */
90
+ export function assertModePermitsCommandType(mode, type) {
91
+ if (!PERMITTED_COMMAND_TYPES[mode].has(type)) {
92
+ throw new StudioCommandError('mode-forbidden', `Command type ${type} is not permitted in ${mode} mode.`);
93
+ }
94
+ }
95
+ /**
96
+ * Enforces the bounded-composition rule for one hybrid structure command:
97
+ * every collection the command inserts into, removes from, moves across, or
98
+ * reorders must be a named slot of a node whose authoring policy mode is
99
+ * `structural`; inserted block types must satisfy the structural node's
100
+ * `allowedBlocks` when declared; subtrees containing a `locked` node are
101
+ * never inserted, removed, moved, or duplicated; and document roots are
102
+ * never in bounds. Batch operations are evaluated sequentially against a
103
+ * trial state so later operations may compose nodes earlier operations
104
+ * introduced. A violation fails closed with `mode-forbidden`; a reference
105
+ * the gate cannot resolve is left for the reducer's canonical failure code.
106
+ *
107
+ * The passed document is consumed as trial scratch state and may be mutated;
108
+ * callers pass a clone.
109
+ */
110
+ export function assertHybridCommandInBounds(document, command) {
111
+ switch (command.type) {
112
+ case 'studio.command/batch': {
113
+ for (const operation of command.payload.operations) {
114
+ const type = operation.type;
115
+ if (type === 'studio.command/batch' ||
116
+ type === 'studio.command/apply-pattern' ||
117
+ type === 'studio.command/reset-inherited-property') {
118
+ // Never legal inside a batch; the reducer's canonical
119
+ // invalid-batch rejection resurfaces when the command executes.
120
+ return;
121
+ }
122
+ if (!HYBRID_BATCHABLE_OPERATION_TYPES.has(operation.type)) {
123
+ throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
124
+ }
125
+ assertHybridOperationInBounds(document, operation);
126
+ try {
127
+ applyOperation(document, operation);
128
+ }
129
+ catch {
130
+ // The trial cannot advance past this operation; the reducer's
131
+ // canonical failure code resurfaces when the command executes.
132
+ return;
133
+ }
134
+ }
135
+ return;
136
+ }
137
+ case 'studio.command/apply-pattern':
138
+ case 'studio.command/reset-inherited-property':
139
+ // Unreachable behind the type gate; kept for fail-closed defence.
140
+ throw new StudioCommandError('mode-forbidden', `Command type ${command.type} is not permitted in hybrid mode.`);
141
+ default:
142
+ assertHybridOperationInBounds(document, command);
143
+ }
144
+ }
145
+ function assertHybridOperationInBounds(document, operation) {
146
+ switch (operation.type) {
147
+ case 'studio.command/insert-node':
148
+ case 'studio.command/restore-node': {
149
+ assertSubtreeUnlocked(operation.payload.node);
150
+ assertComposableDestination(document, operation.payload.destination, operation.payload.node);
151
+ return;
152
+ }
153
+ case 'studio.command/remove-node': {
154
+ const location = locateNode(document.roots, operation.payload.nodeId);
155
+ if (location === undefined) {
156
+ return;
157
+ }
158
+ assertSubtreeUnlocked(location.node);
159
+ assertComposableParent(location.parent);
160
+ return;
161
+ }
162
+ case 'studio.command/move-node': {
163
+ const location = locateNode(document.roots, operation.payload.nodeId);
164
+ if (location === undefined) {
165
+ return;
166
+ }
167
+ assertSubtreeUnlocked(location.node);
168
+ assertComposableParent(location.parent);
169
+ assertComposableDestination(document, operation.payload.destination, location.node);
170
+ return;
171
+ }
172
+ case 'studio.command/duplicate-node': {
173
+ const location = locateNode(document.roots, operation.payload.nodeId);
174
+ if (location === undefined) {
175
+ return;
176
+ }
177
+ assertSubtreeUnlocked(location.node);
178
+ if (operation.payload.destination === undefined) {
179
+ assertComposableParent(location.parent);
180
+ if (location.parent !== undefined) {
181
+ assertAllowedBlock(location.parent, location.node);
182
+ }
183
+ }
184
+ else {
185
+ assertComposableDestination(document, operation.payload.destination, location.node);
186
+ }
187
+ return;
188
+ }
189
+ case 'studio.command/reorder-children': {
190
+ if (operation.payload.parentNodeId === undefined) {
191
+ throw rootsOutOfBounds();
192
+ }
193
+ assertComposableParent(locateNode(document.roots, operation.payload.parentNodeId)?.node);
194
+ return;
195
+ }
196
+ default:
197
+ // Unreachable behind the type gate; kept for fail-closed defence.
198
+ throw new StudioCommandError('mode-forbidden', `Batch operation type ${operation.type} is not permitted in hybrid mode.`);
199
+ }
200
+ }
201
+ function locateNode(nodes, nodeId, parent) {
202
+ for (const node of nodes) {
203
+ if (node.id === nodeId) {
204
+ return parent === undefined ? { node } : { node, parent };
205
+ }
206
+ for (const children of Object.values(node.slots)) {
207
+ const nested = locateNode(children, nodeId, node);
208
+ if (nested !== undefined) {
209
+ return nested;
210
+ }
211
+ }
212
+ }
213
+ return undefined;
214
+ }
215
+ function assertComposableDestination(document, destination, node) {
216
+ if (destination.parentNodeId === undefined) {
217
+ throw rootsOutOfBounds();
218
+ }
219
+ const parent = locateNode(document.roots, destination.parentNodeId)?.node;
220
+ if (parent === undefined) {
221
+ // The reducer's canonical parent-not-found rejection resurfaces.
222
+ return;
223
+ }
224
+ assertComposableParent(parent);
225
+ assertAllowedBlock(parent, node);
226
+ }
227
+ function assertComposableParent(parent) {
228
+ if (parent === undefined) {
229
+ throw rootsOutOfBounds();
230
+ }
231
+ if (parent.authoring.mode !== 'structural') {
232
+ throw new StudioCommandError('mode-forbidden', `Hybrid composition is bounded to structural slots; node ${parent.id} does not declare structural authoring.`);
233
+ }
234
+ }
235
+ function assertAllowedBlock(parent, node) {
236
+ const allowedBlocks = parent.authoring.allowedBlocks;
237
+ if (allowedBlocks !== undefined && !allowedBlocks.includes(node.type)) {
238
+ throw new StudioCommandError('mode-forbidden', `Block type ${node.type} is not an allowed block inside structural node ${parent.id}.`);
239
+ }
240
+ }
241
+ function assertSubtreeUnlocked(node) {
242
+ const stack = [node];
243
+ while (stack.length > 0) {
244
+ const current = stack.pop();
245
+ if (current === undefined) {
246
+ break;
247
+ }
248
+ if (current.authoring.mode === 'locked') {
249
+ throw new StudioCommandError('mode-forbidden', `Node ${current.id} is locked and never changes through hybrid composition.`);
250
+ }
251
+ for (const children of Object.values(current.slots)) {
252
+ stack.push(...children);
253
+ }
254
+ }
255
+ }
256
+ function rootsOutOfBounds() {
257
+ return new StudioCommandError('mode-forbidden', 'Hybrid composition is bounded to structural slots; the document roots are out of bounds.');
258
+ }
259
+ function immutableCommandTypeSet(types) {
260
+ const set = new Set(types);
261
+ const forbidMutation = () => {
262
+ throw new TypeError('The permitted command-type table is immutable.');
263
+ };
264
+ return Object.freeze(Object.assign(set, { add: forbidMutation, clear: forbidMutation, delete: forbidMutation }));
265
+ }
266
+ //# sourceMappingURL=modes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modes.js","sourceRoot":"","sources":["../src/modes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { JsonSchema } from '@kumwe/studio-protocol';
2
+ /** One validation failure, in the shape core diagnostics consume. */
3
+ export interface SchemaValidationError {
4
+ /** JSON Pointer to the failing instance location (`''` is the root). */
5
+ instancePath: string;
6
+ /** The schema keyword that failed. */
7
+ keyword: string;
8
+ /** A human-readable default message. */
9
+ message: string;
10
+ }
11
+ export interface CompileSchemaOptions {
12
+ /**
13
+ * Additional schema documents addressable through their root `$id` for
14
+ * cross-document `$ref` targets. This is the in-memory registry the
15
+ * profile contract describes; runtime network retrieval never happens.
16
+ */
17
+ schemas?: readonly JsonSchema[];
18
+ }
19
+ type SchemaNode = Record<string, unknown>;
20
+ type Subschema = SchemaNode | boolean;
21
+ interface CompiledProgram {
22
+ patterns: WeakMap<SchemaNode, RegExp>;
23
+ references: WeakMap<SchemaNode, Subschema>;
24
+ root: SchemaNode;
25
+ }
26
+ /**
27
+ * A compiled (pre-walked, pre-resolved) profile schema. `validate` mirrors
28
+ * the verdict-plus-`errors` shape of the code-generating validator it
29
+ * replaces: `errors` is `null` after a passing run and carries the failures
30
+ * of the most recent failing run otherwise.
31
+ */
32
+ export declare class CompiledSchemaValidator {
33
+ #private;
34
+ errors: SchemaValidationError[] | null;
35
+ constructor(program: CompiledProgram);
36
+ validate(instance: unknown): boolean;
37
+ }
38
+ /**
39
+ * Compiles a schema for interpretation: validates every keyword against the
40
+ * profile's closed allowlist and operand grammar, compiles bounded lexical
41
+ * patterns, and resolves every `$ref` against the in-memory registry. All
42
+ * structural errors surface here, at compile time, so validation itself is
43
+ * total. Throws `TypeError`/`RangeError` on any schema outside the profile.
44
+ */
45
+ export declare function compileProfileSchema(schema: JsonSchema, options?: CompileSchemaOptions): CompiledSchemaValidator;
46
+ export {};
47
+ //# sourceMappingURL=profile-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-validator.d.ts","sourceRoot":"","sources":["../src/profile-validator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAwFzD,qEAAqE;AACrE,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,YAAY,EAAE,MAAM,CAAC;IACrB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;CACjC;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1C,KAAK,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAgBtC,UAAU,eAAe;IACvB,QAAQ,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC3C,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;;;GAKG;AACH,qBAAa,uBAAuB;;IAC3B,MAAM,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAQ;gBAGlC,OAAO,EAAE,eAAe;IAIpC,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO;CAM5C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,UAAU,EAClB,OAAO,GAAE,oBAAyB,GACjC,uBAAuB,CA6CzB"}