@kubohiroya/turbowarp-extension-data-editor 0.2.0 → 0.2.2

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.
Files changed (68) hide show
  1. package/README.md +9 -6
  2. package/dist/build-info.json +3 -3
  3. package/dist/fixed-input-branches.d.ts +12 -0
  4. package/dist/fixed-input-branches.js +180 -0
  5. package/dist/fixed-input-editor.d.ts +39 -0
  6. package/dist/fixed-input-editor.js +538 -0
  7. package/dist/fixed-input-schema.d.ts +15 -0
  8. package/dist/fixed-input-schema.js +21 -0
  9. package/dist/fixed-input-snapshot.d.ts +7 -0
  10. package/dist/fixed-input-snapshot.js +180 -0
  11. package/dist/fixed-input-types.d.ts +138 -0
  12. package/dist/fixed-input-types.js +23 -0
  13. package/dist/fixed-input-view.d.ts +14 -0
  14. package/dist/fixed-input-view.js +168 -0
  15. package/dist/index.d.ts +6 -0
  16. package/dist/index.js +4 -0
  17. package/dist/react.css +168 -0
  18. package/dist/react.d.ts +8 -0
  19. package/dist/react.js +19 -2
  20. package/dist/registry.d.ts +4 -0
  21. package/dist/registry.js +45 -7
  22. package/dist/rjsf-templates.d.ts +11 -0
  23. package/dist/rjsf-templates.js +129 -0
  24. package/dist/rjsf.d.ts +24 -1
  25. package/dist/rjsf.js +35 -3
  26. package/dist/schema.d.ts +2 -0
  27. package/dist/schema.js +1 -0
  28. package/dist/session.d.ts +3 -1
  29. package/dist/session.js +205 -7
  30. package/dist/turbowarp/bridge.d.ts +2 -1
  31. package/dist/turbowarp/bridge.js +37 -5
  32. package/dist/turbowarp/fixed-fields.d.ts +82 -0
  33. package/dist/turbowarp/fixed-fields.js +311 -0
  34. package/dist/turbowarp/fixed-transaction.d.ts +18 -0
  35. package/dist/turbowarp/fixed-transaction.js +460 -0
  36. package/dist/turbowarp/host.d.ts +3 -8
  37. package/dist/turbowarp/host.js +68 -1
  38. package/dist/turbowarp.d.ts +4 -0
  39. package/dist/turbowarp.js +1 -1
  40. package/dist/types.d.ts +5 -0
  41. package/dist/view.js +4 -0
  42. package/dist/webpack4/index.js +22 -5
  43. package/dist/webpack4/metafile.json +592 -299
  44. package/dist/webpack4/react.js +20 -6
  45. package/dist/webpack4/react.js.map +2 -2
  46. package/dist/webpack4/rjsf.js +450 -60
  47. package/dist/webpack4/rjsf.js.map +4 -4
  48. package/dist/webpack4/schema.js +6 -3
  49. package/dist/webpack4/{shared-KQOUMWJ4.js → shared-75QIWLZY.js} +1129 -1244
  50. package/dist/webpack4/{shared-KQOUMWJ4.js.map → shared-75QIWLZY.js.map} +4 -4
  51. package/dist/webpack4/shared-FYUILHED.js +1 -0
  52. package/dist/webpack4/shared-GQLPPRT2.js +210 -0
  53. package/dist/webpack4/shared-GQLPPRT2.js.map +7 -0
  54. package/dist/webpack4/shared-P2JBRZFP.js +2206 -0
  55. package/dist/webpack4/shared-P2JBRZFP.js.map +7 -0
  56. package/dist/webpack4/turbowarp.js +913 -9
  57. package/dist/webpack4/turbowarp.js.map +4 -4
  58. package/docs/api.md +7 -0
  59. package/docs/fixed-input-contracts.md +77 -0
  60. package/docs/package-distribution.md +5 -0
  61. package/docs/stage-2-publication.ja.md +6 -0
  62. package/package.json +2 -1
  63. package/dist/webpack4/shared-CQB3NG2A.js +0 -1
  64. package/dist/webpack4/shared-MRPGBJIH.js +0 -75
  65. package/dist/webpack4/shared-MRPGBJIH.js.map +0 -7
  66. package/dist/webpack4/shared-N6YQE2X6.js +0 -1029
  67. package/dist/webpack4/shared-N6YQE2X6.js.map +0 -7
  68. /package/dist/webpack4/{shared-CQB3NG2A.js.map → shared-FYUILHED.js.map} +0 -0
package/dist/schema.d.ts CHANGED
@@ -6,3 +6,5 @@ export { validateSchemaInput } from './schema-compose.js';
6
6
  export declare function toValidationIssues(diagnostics: readonly InputDiagnostic[]): readonly ValidationIssue[];
7
7
  export type * from './source-types.js';
8
8
  export { jsonValueSchema, jsonValueSchemaBundle } from './json-value.js';
9
+ export { parseFixedNumberInput } from './fixed-input-schema.js';
10
+ export type { FixedNumberInputResult } from './fixed-input-schema.js';
package/dist/schema.js CHANGED
@@ -84,3 +84,4 @@ export function toValidationIssues(diagnostics) {
84
84
  }
85
85
  }
86
86
  export { jsonValueSchema, jsonValueSchemaBundle } from './json-value.js';
87
+ export { parseFixedNumberInput } from './fixed-input-schema.js';
package/dist/session.d.ts CHANGED
@@ -1,11 +1,13 @@
1
+ import type { FixedInputViewDescription } from './fixed-input-types.js';
1
2
  import type { BlockEditorHost, BlockReference, BlockSnapshot, EditorDefinition, EditorViewContext, JsonObject, SaveResult, SessionState, ValidationIssue } from './types.js';
2
3
  export declare class EditorSession implements EditorViewContext {
3
4
  #private;
4
5
  /** Use EditorRegistry.open() to construct sessions from a captured host snapshot. */
5
- constructor(definition: EditorDefinition, snapshot: BlockSnapshot, host: BlockEditorHost, isRegistered?: () => boolean);
6
+ constructor(definition: EditorDefinition, snapshot: BlockSnapshot, host: BlockEditorHost, isRegistered?: () => boolean, subscribeRegistrationChanges?: (listener: () => void) => () => void);
6
7
  /** Stable instance identity remains available after the session closes. */
7
8
  get reference(): BlockReference;
8
9
  getDraft(): JsonObject;
10
+ getFixedInputView(): FixedInputViewDescription | undefined;
9
11
  setDraft(draft: JsonObject): void;
10
12
  setValidationIssues(issues: readonly ValidationIssue[]): void;
11
13
  getState(): SessionState;
package/dist/session.js CHANGED
@@ -9,14 +9,19 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
9
9
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
10
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
11
  };
12
- var _EditorSession_instances, _EditorSession_draft, _EditorSession_status, _EditorSession_issues, _EditorSession_error, _EditorSession_listeners, _EditorSession_view, _EditorSession_definition, _EditorSession_snapshot, _EditorSession_host, _EditorSession_isRegistered, _EditorSession_prepareChanges, _EditorSession_copyIssues, _EditorSession_copyDraft, _EditorSession_assertOpen, _EditorSession_finish, _EditorSession_notify, _EditorSession_reportObserverError;
12
+ var _EditorSession_instances, _EditorSession_draft, _EditorSession_status, _EditorSession_issues, _EditorSession_error, _EditorSession_listeners, _EditorSession_view, _EditorSession_definition, _EditorSession_snapshot, _EditorSession_host, _EditorSession_fixedPort, _EditorSession_isRegistered, _EditorSession_subscribeRegistrationChanges, _EditorSession_unsubscribeFixedScope, _EditorSession_unsubscribeFixedRegistration, _EditorSession_fixedSavingController, _EditorSession_saveFixed, _EditorSession_prepareChanges, _EditorSession_copyIssues, _EditorSession_copyDraft, _EditorSession_assertOpen, _EditorSession_finish, _EditorSession_notify, _EditorSession_reportObserverError;
13
13
  import { captureReference, captureSnapshot, cloneJson, isLiteral, sameSnapshot } from './data.js';
14
14
  import { BlockEditorConflictError } from './types.js';
15
15
  import { EditorView } from './view.js';
16
16
  import { isPreparedEditor, capturePreparedSave } from './prepared-save.js';
17
+ import { isFixedInputEditor, captureFixedPreparedSave } from './fixed-input-editor.js';
18
+ import { captureFixedSnapshot, sameFixedSnapshot } from './fixed-input-snapshot.js';
19
+ import { supportsFixedInputEditing } from './fixed-input-types.js';
20
+ import { snapshotJson, isJsonRecord } from './schema-json.js';
21
+ import { validateFixedBranchChanges } from './fixed-input-branches.js';
17
22
  export class EditorSession {
18
23
  /** Use EditorRegistry.open() to construct sessions from a captured host snapshot. */
19
- constructor(definition, snapshot, host, isRegistered) {
24
+ constructor(definition, snapshot, host, isRegistered, subscribeRegistrationChanges) {
20
25
  _EditorSession_instances.add(this);
21
26
  _EditorSession_draft.set(this, void 0);
22
27
  _EditorSession_status.set(this, 'editing');
@@ -27,12 +32,68 @@ export class EditorSession {
27
32
  _EditorSession_definition.set(this, void 0);
28
33
  _EditorSession_snapshot.set(this, void 0);
29
34
  _EditorSession_host.set(this, void 0);
35
+ _EditorSession_fixedPort.set(this, void 0);
30
36
  _EditorSession_isRegistered.set(this, void 0);
37
+ _EditorSession_subscribeRegistrationChanges.set(this, void 0);
38
+ _EditorSession_unsubscribeFixedScope.set(this, void 0);
39
+ _EditorSession_unsubscribeFixedRegistration.set(this, void 0);
40
+ _EditorSession_fixedSavingController.set(this, void 0);
31
41
  __classPrivateFieldSet(this, _EditorSession_isRegistered, isRegistered, "f");
42
+ __classPrivateFieldSet(this, _EditorSession_subscribeRegistrationChanges, subscribeRegistrationChanges, "f");
32
43
  __classPrivateFieldSet(this, _EditorSession_definition, definition, "f");
33
- __classPrivateFieldSet(this, _EditorSession_snapshot, captureSnapshot(snapshot, captureReference(snapshot)), "f");
44
+ __classPrivateFieldSet(this, _EditorSession_snapshot, isFixedInputEditor(definition)
45
+ ? captureFixedSnapshot(snapshot, captureReference(snapshot), definition)
46
+ : captureSnapshot(snapshot, captureReference(snapshot)), "f");
34
47
  __classPrivateFieldSet(this, _EditorSession_host, host, "f");
35
- __classPrivateFieldSet(this, _EditorSession_draft, __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyDraft).call(this, definition.read(__classPrivateFieldGet(this, _EditorSession_snapshot, "f"))), "f");
48
+ __classPrivateFieldSet(this, _EditorSession_fixedPort, isFixedInputEditor(definition) && supportsFixedInputEditing(host) ? host.fixedInputs : undefined, "f");
49
+ if (isFixedInputEditor(definition) && !supportsFixedInputEditing(host))
50
+ throw new TypeError('Fixed input editors require a compatible host.');
51
+ __classPrivateFieldSet(this, _EditorSession_draft, __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyDraft).call(this, isFixedInputEditor(definition)
52
+ ? definition.readFixed(__classPrivateFieldGet(this, _EditorSession_snapshot, "f")) : definition.read(__classPrivateFieldGet(this, _EditorSession_snapshot, "f"))), "f");
53
+ if (isFixedInputEditor(definition) && __classPrivateFieldGet(this, _EditorSession_subscribeRegistrationChanges, "f")) {
54
+ const unsubscribe = __classPrivateFieldGet(this, _EditorSession_subscribeRegistrationChanges, "f").call(this, () => {
55
+ var _a;
56
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this) && (__classPrivateFieldGet(this, _EditorSession_status, "f") === 'editing' || __classPrivateFieldGet(this, _EditorSession_status, "f") === 'saving')) {
57
+ (_a = __classPrivateFieldGet(this, _EditorSession_fixedSavingController, "f")) === null || _a === void 0 ? void 0 : _a.abort(new BlockEditorConflictError());
58
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'disposed');
59
+ }
60
+ });
61
+ if (__classPrivateFieldGet(this, _EditorSession_status, "f") === 'editing')
62
+ __classPrivateFieldSet(this, _EditorSession_unsubscribeFixedRegistration, unsubscribe, "f");
63
+ else
64
+ unsubscribe();
65
+ }
66
+ try {
67
+ if (isFixedInputEditor(definition) && __classPrivateFieldGet(this, _EditorSession_fixedPort, "f")) {
68
+ let subscribe;
69
+ for (let item = __classPrivateFieldGet(this, _EditorSession_fixedPort, "f"), depth = 0; item && depth < 64; item = Object.getPrototypeOf(item), depth++) {
70
+ const property = Object.getOwnPropertyDescriptor(item, 'subscribeInvalidation');
71
+ if (property) {
72
+ subscribe = 'value' in property ? property.value : undefined;
73
+ break;
74
+ }
75
+ }
76
+ if (typeof subscribe === 'function') {
77
+ const unsubscribe = subscribe.call(__classPrivateFieldGet(this, _EditorSession_fixedPort, "f"), this.reference, definition, () => {
78
+ var _a;
79
+ if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'editing' && __classPrivateFieldGet(this, _EditorSession_status, "f") !== 'saving')
80
+ return;
81
+ (_a = __classPrivateFieldGet(this, _EditorSession_fixedSavingController, "f")) === null || _a === void 0 ? void 0 : _a.abort(new BlockEditorConflictError());
82
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'disposed');
83
+ });
84
+ if (typeof unsubscribe !== 'function')
85
+ throw new TypeError('Invalid fixed scope subscription.');
86
+ if (__classPrivateFieldGet(this, _EditorSession_status, "f") === 'editing')
87
+ __classPrivateFieldSet(this, _EditorSession_unsubscribeFixedScope, unsubscribe, "f");
88
+ else
89
+ unsubscribe();
90
+ }
91
+ }
92
+ }
93
+ catch (error) {
94
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'disposed');
95
+ throw error;
96
+ }
36
97
  }
37
98
  /** Stable instance identity remains available after the session closes. */
38
99
  get reference() {
@@ -42,6 +103,36 @@ export class EditorSession {
42
103
  __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_assertOpen).call(this);
43
104
  return cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f"));
44
105
  }
106
+ getFixedInputView() {
107
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_assertOpen).call(this);
108
+ const definition = __classPrivateFieldGet(this, _EditorSession_definition, "f");
109
+ if (!isFixedInputEditor(definition) || !definition.describeFixed)
110
+ return undefined;
111
+ let description;
112
+ try {
113
+ description = definition.describeFixed(__classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyDraft).call(this, __classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f"));
114
+ const captured = snapshotJson(description);
115
+ if (!isJsonRecord(captured) || !isJsonRecord(captured.inputs) ||
116
+ !Array.isArray(captured.issues) || !Array.isArray(captured.branches)) {
117
+ throw new TypeError('Invalid fixed input presentation.');
118
+ }
119
+ const freeze = (value) => {
120
+ if (value && typeof value === 'object') {
121
+ Object.values(value).forEach(freeze);
122
+ Object.freeze(value);
123
+ }
124
+ };
125
+ freeze(captured);
126
+ return captured;
127
+ }
128
+ catch (_a) {
129
+ try {
130
+ void Promise.prototype.then.call(description, () => undefined, () => undefined);
131
+ }
132
+ catch ( /* Never inspect arbitrary thenables. */_b) { /* Never inspect arbitrary thenables. */ }
133
+ throw new TypeError('Invalid fixed input presentation.');
134
+ }
135
+ }
45
136
  setDraft(draft) {
46
137
  if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'editing')
47
138
  throw new Error('The session is not editable.');
@@ -82,6 +173,8 @@ export class EditorSession {
82
173
  try {
83
174
  if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
84
175
  throw new BlockEditorConflictError('The source editor registration expired.');
176
+ if (isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f")))
177
+ return await __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_saveFixed).call(this);
85
178
  const prepared = isPreparedEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f"))
86
179
  ? capturePreparedSave(__classPrivateFieldGet(this, _EditorSession_definition, "f"), cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f")) : undefined;
87
180
  const issues = prepared ? (prepared.kind === 'invalid' ? prepared.issues : [])
@@ -135,7 +228,73 @@ export class EditorSession {
135
228
  return true;
136
229
  }
137
230
  }
138
- _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _EditorSession_issues = new WeakMap(), _EditorSession_error = new WeakMap(), _EditorSession_listeners = new WeakMap(), _EditorSession_view = new WeakMap(), _EditorSession_definition = new WeakMap(), _EditorSession_snapshot = new WeakMap(), _EditorSession_host = new WeakMap(), _EditorSession_isRegistered = new WeakMap(), _EditorSession_instances = new WeakSet(), _EditorSession_prepareChanges = function _EditorSession_prepareChanges(patch) {
231
+ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _EditorSession_issues = new WeakMap(), _EditorSession_error = new WeakMap(), _EditorSession_listeners = new WeakMap(), _EditorSession_view = new WeakMap(), _EditorSession_definition = new WeakMap(), _EditorSession_snapshot = new WeakMap(), _EditorSession_host = new WeakMap(), _EditorSession_fixedPort = new WeakMap(), _EditorSession_isRegistered = new WeakMap(), _EditorSession_subscribeRegistrationChanges = new WeakMap(), _EditorSession_unsubscribeFixedScope = new WeakMap(), _EditorSession_unsubscribeFixedRegistration = new WeakMap(), _EditorSession_fixedSavingController = new WeakMap(), _EditorSession_instances = new WeakSet(), _EditorSession_saveFixed = async function _EditorSession_saveFixed() {
232
+ var _a;
233
+ const definition = __classPrivateFieldGet(this, _EditorSession_definition, "f");
234
+ if (!isFixedInputEditor(definition))
235
+ throw new TypeError('Fixed input capability is unavailable.');
236
+ if (!supportsFixedInputEditing(__classPrivateFieldGet(this, _EditorSession_host, "f")) || __classPrivateFieldGet(this, _EditorSession_host, "f").fixedInputs !== __classPrivateFieldGet(this, _EditorSession_fixedPort, "f")) {
237
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'disposed');
238
+ throw new BlockEditorConflictError('The fixed input capability changed.');
239
+ }
240
+ const snapshot = __classPrivateFieldGet(this, _EditorSession_snapshot, "f");
241
+ const prepared = captureFixedPreparedSave(definition, __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyDraft).call(this, __classPrivateFieldGet(this, _EditorSession_draft, "f")), snapshot);
242
+ if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'saving')
243
+ throw new BlockEditorConflictError();
244
+ if (prepared.kind === 'invalid') {
245
+ __classPrivateFieldSet(this, _EditorSession_issues, __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyIssues).call(this, prepared.issues), "f");
246
+ return { status: 'invalid', issues: __classPrivateFieldGet(this, _EditorSession_issues, "f") };
247
+ }
248
+ const changes = __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_prepareChanges).call(this, prepared.changes);
249
+ const port = __classPrivateFieldGet(this, _EditorSession_host, "f").fixedInputs;
250
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
251
+ throw new BlockEditorConflictError('The fixed editor registration expired.');
252
+ const current = port.readBlock(snapshot, definition);
253
+ if (!current)
254
+ throw new BlockEditorConflictError();
255
+ try {
256
+ const captured = captureFixedSnapshot(current, snapshot, definition);
257
+ if (captured.fixedContext.generation !== snapshot.fixedContext.generation) {
258
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'disposed');
259
+ throw new BlockEditorConflictError();
260
+ }
261
+ if (!sameFixedSnapshot(snapshot, captured))
262
+ throw new BlockEditorConflictError();
263
+ }
264
+ catch (_b) {
265
+ throw new BlockEditorConflictError();
266
+ }
267
+ if (!supportsFixedInputEditing(__classPrivateFieldGet(this, _EditorSession_host, "f")) || __classPrivateFieldGet(this, _EditorSession_host, "f").fixedInputs !== port ||
268
+ (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this)))
269
+ throw new BlockEditorConflictError('The fixed editor registration expired.');
270
+ if (changes.length > 0) {
271
+ const controller = new AbortController();
272
+ __classPrivateFieldSet(this, _EditorSession_fixedSavingController, controller, "f");
273
+ const context = prepared.context;
274
+ const unsubscribe = (_a = __classPrivateFieldGet(this, _EditorSession_subscribeRegistrationChanges, "f")) === null || _a === void 0 ? void 0 : _a.call(this, () => {
275
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
276
+ controller.abort(new BlockEditorConflictError('The fixed editor registration expired.'));
277
+ });
278
+ try {
279
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
280
+ throw new BlockEditorConflictError('The fixed editor registration expired.');
281
+ await port.commit(Object.freeze({ expected: snapshot, changes, context, signal: controller.signal }));
282
+ if (controller.signal.aborted)
283
+ throw new BlockEditorConflictError('The fixed editor registration expired.');
284
+ }
285
+ catch (error) {
286
+ if (controller.signal.aborted)
287
+ throw new BlockEditorConflictError('The fixed editor registration expired.');
288
+ throw error;
289
+ }
290
+ finally {
291
+ unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe();
292
+ __classPrivateFieldSet(this, _EditorSession_fixedSavingController, undefined, "f");
293
+ }
294
+ }
295
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_finish).call(this, 'saved');
296
+ return { status: 'saved', changed: changes.length > 0 };
297
+ }, _EditorSession_prepareChanges = function _EditorSession_prepareChanges(patch) {
139
298
  if (!Array.isArray(patch))
140
299
  throw new TypeError('createPatch() must return an array.');
141
300
  const seen = new Set();
@@ -151,11 +310,23 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
151
310
  if (!slot || slot.kind !== 'literal') {
152
311
  throw new TypeError('Only existing literal arguments can be changed.');
153
312
  }
154
- if (slot.value !== change.value)
313
+ if (isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f"))) {
314
+ const metadata = __classPrivateFieldGet(this, _EditorSession_snapshot, "f").fixedContext.inputs[change.argument];
315
+ if (!metadata || metadata.role !== 'editable' || (metadata.source !== 'field' && metadata.source !== 'shadow'))
316
+ throw new TypeError('Fixed patches require editable literal fields.');
317
+ if (!Object.is(slot.value, change.value)) {
318
+ changes.push(Object.freeze({ argument: change.argument, value: change.value }));
319
+ }
320
+ }
321
+ else if (slot.value !== change.value)
155
322
  changes.push(Object.freeze({ ...change }));
156
323
  }
324
+ if (isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f")) && validateFixedBranchChanges(__classPrivateFieldGet(this, _EditorSession_definition, "f"), __classPrivateFieldGet(this, _EditorSession_snapshot, "f"), changes).length)
325
+ throw new TypeError('Fixed dependency validation is unavailable.');
157
326
  return Object.freeze(changes);
158
327
  }, _EditorSession_copyIssues = function _EditorSession_copyIssues(issues) {
328
+ if (isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f")))
329
+ issues = snapshotJson(issues);
159
330
  if (!Array.isArray(issues))
160
331
  throw new TypeError('Expected a validation issue array.');
161
332
  return Object.freeze(issues.map(issue => {
@@ -169,7 +340,18 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
169
340
  if (!draft || typeof draft !== 'object' || Array.isArray(draft)) {
170
341
  throw new TypeError('The editor draft must be a JSON object.');
171
342
  }
172
- return cloneJson(draft);
343
+ if (!isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f")))
344
+ return cloneJson(draft);
345
+ try {
346
+ return snapshotJson(draft);
347
+ }
348
+ catch (error) {
349
+ try {
350
+ void Promise.prototype.then.call(draft, () => undefined, () => undefined);
351
+ }
352
+ catch ( /* Synchronous fixed drafts never inspect arbitrary thenables. */_a) { /* Synchronous fixed drafts never inspect arbitrary thenables. */ }
353
+ throw error;
354
+ }
173
355
  }, _EditorSession_assertOpen = function _EditorSession_assertOpen() {
174
356
  if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'editing' && __classPrivateFieldGet(this, _EditorSession_status, "f") !== 'saving') {
175
357
  throw new Error('The session is closed.');
@@ -177,6 +359,22 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
177
359
  }, _EditorSession_finish = function _EditorSession_finish(status) {
178
360
  __classPrivateFieldSet(this, _EditorSession_status, status, "f");
179
361
  __classPrivateFieldSet(this, _EditorSession_draft, {}, "f");
362
+ const unsubscribe = __classPrivateFieldGet(this, _EditorSession_unsubscribeFixedScope, "f");
363
+ __classPrivateFieldSet(this, _EditorSession_unsubscribeFixedScope, undefined, "f");
364
+ try {
365
+ unsubscribe === null || unsubscribe === void 0 ? void 0 : unsubscribe();
366
+ }
367
+ catch (error) {
368
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_reportObserverError).call(this, error);
369
+ }
370
+ const unsubscribeRegistration = __classPrivateFieldGet(this, _EditorSession_unsubscribeFixedRegistration, "f");
371
+ __classPrivateFieldSet(this, _EditorSession_unsubscribeFixedRegistration, undefined, "f");
372
+ try {
373
+ unsubscribeRegistration === null || unsubscribeRegistration === void 0 ? void 0 : unsubscribeRegistration();
374
+ }
375
+ catch (error) {
376
+ __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_reportObserverError).call(this, error);
377
+ }
180
378
  __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_notify).call(this);
181
379
  try {
182
380
  __classPrivateFieldGet(this, _EditorSession_view, "f").unmount();
@@ -1,5 +1,5 @@
1
1
  export default createBlockEditorBridge;
2
- declare function createBlockEditorBridge({ ScratchBlocks, workspace, vm, service, label, canOpen, onOpen, onError, descendants }: {
2
+ declare function createBlockEditorBridge({ ScratchBlocks, workspace, vm, service, label, canOpen, onOpen, onError, descendants, fixedInputs }: {
3
3
  ScratchBlocks: any;
4
4
  workspace: any;
5
5
  vm: any;
@@ -9,6 +9,7 @@ declare function createBlockEditorBridge({ ScratchBlocks, workspace, vm, service
9
9
  onOpen: any;
10
10
  onError: any;
11
11
  descendants?: boolean | undefined;
12
+ fixedInputs?: boolean | undefined;
12
13
  }): {
13
14
  refresh: () => void;
14
15
  dispose: () => void;
@@ -1,22 +1,32 @@
1
1
  import createBlockEditorHost from './host.js';
2
2
  import bindBlockEditorIcon from './icon.js';
3
3
  import readBlockEditorAppearance from './appearance.js';
4
- import { supportsDescendantEditing } from '../index.js';
4
+ import { supportsDescendantEditing, supportsFixedInputEditing } from '../index.js';
5
5
  import createBlockEditorErrorSession from './error-session.js';
6
- const openBlockEditorSession = ({ registry, reference, host, descendants }) => (descendants && supportsDescendantEditing(host) ?
7
- registry.openDescendants(reference, host) : registry.open(reference, host));
8
- const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label, canOpen, onOpen, onError, descendants = false }) => {
6
+ const fixedDeclaration = (registry, snapshot) => snapshot && typeof registry.resolveFixed === 'function' &&
7
+ registry.resolveFixed(snapshot.opcode);
8
+ const openBlockEditorSession = ({ registry, reference, host, descendants }) => {
9
+ const snapshot = host.readBlock ? host.readBlock(reference) : null;
10
+ // A fixed registration owns only this block; legacy aggregate traversal stays fail-closed.
11
+ if (fixedDeclaration(registry, snapshot))
12
+ return supportsFixedInputEditing(host) ? registry.open(reference, host) : undefined;
13
+ return descendants && supportsDescendantEditing(host) ?
14
+ registry.openDescendants(reference, host) : registry.open(reference, host);
15
+ };
16
+ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label, canOpen, onOpen, onError, descendants = false, fixedInputs = false }) => {
9
17
  const host = createBlockEditorHost({ ScratchBlocks,
10
18
  workspace,
11
19
  vm,
12
20
  registry: service.registry,
13
21
  enableDescendants: descendants,
22
+ enableFixedInputs: fixedInputs,
14
23
  onError });
15
24
  const decorations = new Map();
16
25
  let disposed = false;
17
26
  let timer = null;
18
27
  let activeSession = null;
19
28
  let openingSnapshot = null;
29
+ let openingFixedDeclaration = null;
20
30
  let stopWaiting = null;
21
31
  const endSession = () => {
22
32
  const session = activeSession;
@@ -41,6 +51,7 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
41
51
  }
42
52
  };
43
53
  const checkSession = () => {
54
+ var _a;
44
55
  // The host owns rollback. Its synchronous transaction must retain the draft on failure.
45
56
  if (host.isCommitting())
46
57
  return;
@@ -49,6 +60,14 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
49
60
  return;
50
61
  const current = typeof activeSession.getNodes === 'function' ?
51
62
  host.descendants.readSubtree(activeSession.reference) : host.readBlock(activeSession.reference);
63
+ if (openingFixedDeclaration) {
64
+ // Same-target external edits conflict at save while the session retains its draft.
65
+ // Project/target/registration replacement ends the session and drops that draft.
66
+ if (!current || ((_a = current.fixedContext) === null || _a === void 0 ? void 0 : _a.generation) !== openingSnapshot.fixedContext.generation ||
67
+ fixedDeclaration(service.registry, current) !== openingFixedDeclaration)
68
+ endSession();
69
+ return;
70
+ }
52
71
  if (!current || JSON.stringify(current) !== JSON.stringify(openingSnapshot))
53
72
  endSession();
54
73
  };
@@ -56,6 +75,8 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
56
75
  if (disposed || !vm.editingTarget || !canOpen() || !service.registry.resolve(block.type))
57
76
  return false;
58
77
  const snapshot = host.readBlock({ targetId: vm.editingTarget.id, blockId: block.id });
78
+ if (fixedDeclaration(service.registry, snapshot))
79
+ return supportsFixedInputEditing(host);
59
80
  return snapshot && Object.values(snapshot.arguments).every(slot => slot.kind === 'literal');
60
81
  };
61
82
  const open = block => {
@@ -71,8 +92,12 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
71
92
  activeSession = session;
72
93
  openingSnapshot = typeof session.getNodes === 'function' ?
73
94
  host.descendants.readSubtree(session.reference) : host.readBlock(session.reference);
95
+ openingFixedDeclaration = fixedDeclaration(service.registry, openingSnapshot) || null;
74
96
  const labels = {};
75
97
  const appearances = Object.create(null);
98
+ const rootAppearance = readBlockEditorAppearance(block, ScratchBlocks);
99
+ appearances[reference.blockId] = rootAppearance;
100
+ labels[reference.blockId] = rootAppearance.name || block.type;
76
101
  if (typeof session.getNodes === 'function') {
77
102
  for (const node of session.getNodes()) {
78
103
  const source = workspace.getBlockById(node.reference.blockId);
@@ -88,6 +113,7 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
88
113
  onError(error);
89
114
  activeSession = createBlockEditorErrorSession(reference, error);
90
115
  openingSnapshot = null;
116
+ openingFixedDeclaration = null;
91
117
  onOpen(activeSession);
92
118
  }
93
119
  };
@@ -137,7 +163,13 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
137
163
  };
138
164
  const unregister = service.subscribe(() => {
139
165
  // Aggregate sessions observe relevant registry changes themselves.
140
- if (!activeSession || typeof activeSession.getNodes !== 'function') {
166
+ if (openingFixedDeclaration && activeSession) {
167
+ if (service.registry.resolveFixed(openingSnapshot.opcode) !== openingFixedDeclaration) {
168
+ host.invalidate();
169
+ endSession();
170
+ }
171
+ }
172
+ else if (!activeSession || typeof activeSession.getNodes !== 'function') {
141
173
  host.invalidate();
142
174
  endSession();
143
175
  }
@@ -0,0 +1,82 @@
1
+ /** Freeze native method identities once when the host attaches, before opening editors. */
2
+ export function initializeFixedFields(ScratchBlocks: any): void;
3
+ /** Native objects stay local; only primitive metadata is returned in snapshots. */
4
+ export function inspectFixedArgument({ ScratchBlocks, block, vmBlock, target, argument, role, identify, extensionId }: {
5
+ ScratchBlocks: any;
6
+ block: any;
7
+ vmBlock: any;
8
+ target: any;
9
+ argument: any;
10
+ role: any;
11
+ identify: any;
12
+ extensionId: any;
13
+ }): {
14
+ slot: {
15
+ kind: string;
16
+ value: string | number | boolean;
17
+ } | {
18
+ kind: string;
19
+ value?: never;
20
+ };
21
+ metadata: {
22
+ role: any;
23
+ source: any;
24
+ identity: string;
25
+ reason: any;
26
+ };
27
+ signatureParts: any[];
28
+ } | {
29
+ slot: {
30
+ kind: string;
31
+ value?: never;
32
+ };
33
+ metadata: {
34
+ role: any;
35
+ source: string;
36
+ identity: string;
37
+ field?: never;
38
+ };
39
+ signatureParts: any[];
40
+ } | {
41
+ signatureParts: any[];
42
+ binding?: {
43
+ restoreState?: {
44
+ colors: any[];
45
+ hsv: any[][];
46
+ blockProperties: any;
47
+ };
48
+ block: any;
49
+ field: any;
50
+ fieldName: any;
51
+ value: string;
52
+ vmBlock: any;
53
+ kind: string;
54
+ Class: any;
55
+ prototype: any;
56
+ allowedValues: readonly string[] | null | undefined;
57
+ restoreValue: any;
58
+ rawState: any;
59
+ restoreHandles: any;
60
+ restoreDom: any;
61
+ };
62
+ slot: {
63
+ kind: string;
64
+ value: string;
65
+ };
66
+ metadata: {
67
+ role: any;
68
+ source: string;
69
+ identity: string;
70
+ field: {
71
+ blockId: any;
72
+ name: any;
73
+ type: string | undefined;
74
+ };
75
+ };
76
+ } | null;
77
+ /** Validate the exact saved primitive; native setters must not silently normalize it. */
78
+ export function prepareFixedChange(binding: any, value: any): any;
79
+ /** Capture a later external value without invoking replacement field methods. */
80
+ export function captureFixedFieldState(binding: any): any;
81
+ /** Restore raw text and the standard color field's additional block/UI state. */
82
+ export function restoreFixedField(binding: any): void;