@kubohiroya/turbowarp-extension-data-editor 0.1.0 → 0.2.1

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 (123) hide show
  1. package/README.md +30 -6
  2. package/dist/build-info.json +7 -2
  3. package/dist/descendants.js +11 -2
  4. package/dist/fixed-input-branches.d.ts +12 -0
  5. package/dist/fixed-input-branches.js +180 -0
  6. package/dist/fixed-input-editor.d.ts +39 -0
  7. package/dist/fixed-input-editor.js +538 -0
  8. package/dist/fixed-input-schema.d.ts +15 -0
  9. package/dist/fixed-input-schema.js +21 -0
  10. package/dist/fixed-input-snapshot.d.ts +7 -0
  11. package/dist/fixed-input-snapshot.js +180 -0
  12. package/dist/fixed-input-types.d.ts +138 -0
  13. package/dist/fixed-input-types.js +23 -0
  14. package/dist/fixed-input-view.d.ts +14 -0
  15. package/dist/fixed-input-view.js +168 -0
  16. package/dist/index.d.ts +7 -0
  17. package/dist/index.js +4 -0
  18. package/dist/json-value.d.ts +4 -0
  19. package/dist/json-value.js +12 -0
  20. package/dist/prepared-save.d.ts +5 -0
  21. package/dist/prepared-save.js +47 -0
  22. package/dist/prepared-types.d.ts +13 -0
  23. package/dist/prepared-types.js +1 -0
  24. package/dist/react.css +42 -0
  25. package/dist/react.d.ts +3 -0
  26. package/dist/react.js +10 -1
  27. package/dist/registry.d.ts +6 -0
  28. package/dist/registry.js +98 -48
  29. package/dist/rjsf.d.ts +48 -1
  30. package/dist/rjsf.js +92 -8
  31. package/dist/schema-compose.d.ts +6 -0
  32. package/dist/schema-compose.js +103 -0
  33. package/dist/schema-engine.d.ts +18 -0
  34. package/dist/schema-engine.js +298 -0
  35. package/dist/schema-json.d.ts +10 -0
  36. package/dist/schema-json.js +68 -0
  37. package/dist/schema-types.d.ts +161 -0
  38. package/dist/schema-types.js +2 -0
  39. package/dist/schema-view.d.ts +7 -0
  40. package/dist/schema-view.js +102 -0
  41. package/dist/schema.d.ts +10 -0
  42. package/dist/schema.js +87 -0
  43. package/dist/session.d.ts +3 -1
  44. package/dist/session.js +220 -9
  45. package/dist/source-document.d.ts +3 -0
  46. package/dist/source-document.js +415 -0
  47. package/dist/source-editor.d.ts +13 -0
  48. package/dist/source-editor.js +235 -0
  49. package/dist/source-schema-hints.d.ts +3 -0
  50. package/dist/source-schema-hints.js +13 -0
  51. package/dist/source-types.d.ts +47 -0
  52. package/dist/source-types.js +1 -0
  53. package/dist/source-view.d.ts +3 -0
  54. package/dist/source-view.js +318 -0
  55. package/dist/turbowarp/bridge.d.ts +2 -1
  56. package/dist/turbowarp/bridge.js +34 -5
  57. package/dist/turbowarp/fixed-fields.d.ts +82 -0
  58. package/dist/turbowarp/fixed-fields.js +311 -0
  59. package/dist/turbowarp/fixed-transaction.d.ts +18 -0
  60. package/dist/turbowarp/fixed-transaction.js +460 -0
  61. package/dist/turbowarp/host.d.ts +3 -8
  62. package/dist/turbowarp/host.js +68 -1
  63. package/dist/turbowarp.d.ts +4 -0
  64. package/dist/turbowarp.js +1 -1
  65. package/dist/types.d.ts +7 -4
  66. package/dist/view.js +4 -0
  67. package/dist/webpack4/index.js +24 -5
  68. package/dist/webpack4/metafile.json +9886 -8710
  69. package/dist/webpack4/react.js +11 -2
  70. package/dist/webpack4/react.js.map +2 -2
  71. package/dist/webpack4/rjsf.js +15205 -20951
  72. package/dist/webpack4/rjsf.js.map +4 -4
  73. package/dist/webpack4/schema.js +20 -0
  74. package/dist/webpack4/shared-75QIWLZY.js +8375 -0
  75. package/dist/webpack4/shared-75QIWLZY.js.map +7 -0
  76. package/dist/webpack4/shared-BKTRZUZH.js +42 -0
  77. package/dist/webpack4/{shared-KIFRVTSM.js.map → shared-BKTRZUZH.js.map} +1 -1
  78. package/dist/webpack4/shared-FYUILHED.js +1 -0
  79. package/dist/webpack4/shared-FYUILHED.js.map +7 -0
  80. package/dist/webpack4/shared-GQLPPRT2.js +210 -0
  81. package/dist/webpack4/shared-GQLPPRT2.js.map +7 -0
  82. package/dist/webpack4/shared-P2JBRZFP.js +2206 -0
  83. package/dist/webpack4/shared-P2JBRZFP.js.map +7 -0
  84. package/dist/webpack4/{shared-KIFRVTSM.js → shared-RN7GOT65.js} +2 -41
  85. package/dist/webpack4/shared-RN7GOT65.js.map +7 -0
  86. package/dist/webpack4/turbowarp.js +912 -9
  87. package/dist/webpack4/turbowarp.js.map +4 -4
  88. package/docs/README.md +1 -0
  89. package/docs/block-editor-e2e.md +98 -16
  90. package/docs/ci-success-gate.md +84 -0
  91. package/docs/editor/issue-12-public-validation/README.md +61 -0
  92. package/docs/editor/issue-12-public-validation/dark-invalid.png +0 -0
  93. package/docs/editor/issue-12-public-validation/dark-styles.json +173 -0
  94. package/docs/editor/issue-12-public-validation/dark-valid.png +0 -0
  95. package/docs/editor/issue-12-public-validation/deployment-target.json +5 -0
  96. package/docs/editor/issue-12-public-validation/deployment-wait.json +7 -0
  97. package/docs/editor/issue-12-public-validation/light-invalid.png +0 -0
  98. package/docs/editor/issue-12-public-validation/light-styles.json +173 -0
  99. package/docs/editor/issue-12-public-validation/light-valid.png +0 -0
  100. package/docs/editor/issue-12-public-validation/provenance.json +88 -0
  101. package/docs/editor/issue-12-public-validation/results.json +677 -0
  102. package/docs/editor/issue-12-public-validation/summary.json +206 -0
  103. package/docs/fixed-input-contracts.md +77 -0
  104. package/docs/github-pages.md +48 -41
  105. package/docs/package-distribution.md +2 -2
  106. package/docs/schema-stage1-browser.json +10 -0
  107. package/docs/schema-stage1-contracts.json +242 -0
  108. package/docs/schema-stage1-dependencies.json +202 -0
  109. package/docs/schema-stage1-git-artifact-20261018.ja.md +17 -0
  110. package/docs/schema-stage1-profile-compat.json +30 -0
  111. package/docs/schema-stage1-review-fixes-20261018.ja.md +36 -0
  112. package/docs/schema-stage1-verification.json +541 -0
  113. package/docs/schema-stage1.ja.md +80 -0
  114. package/docs/schema.md +43 -0
  115. package/docs/source-forms.ja.md +19 -0
  116. package/docs/stage-2-publication.ja.md +35 -0
  117. package/docs/template-fixture-separation.ja.md +43 -0
  118. package/package.json +18 -3
  119. package/webpack4.cjs +1 -1
  120. package/dist/webpack4/shared-CQB3NG2A.js +0 -1
  121. package/dist/webpack4/shared-WHOAW2VF.js +0 -957
  122. package/dist/webpack4/shared-WHOAW2VF.js.map +0 -7
  123. /package/dist/webpack4/{shared-CQB3NG2A.js.map → schema.js.map} +0 -0
@@ -0,0 +1,102 @@
1
+ import { Ajv } from 'ajv';
2
+ import { Ajv2020 } from 'ajv/dist/2020.js';
3
+ import formats from 'ajv-formats';
4
+ import uri from 'fast-uri';
5
+ import { prepare } from './schema-engine.js';
6
+ import { snapshotJson } from './schema-json.js';
7
+ /** RJSF v5 only resolves fragment pointers; flatten a private, already checked resource graph. */
8
+ export function schemaView(input) {
9
+ const bundle = snapshotJson(input);
10
+ const ajv = bundle.dialect === 'draft-07' ? new Ajv({ strict: false }) : new Ajv2020({ strict: false });
11
+ formats.default(ajv);
12
+ const prepared = prepare(bundle, ajv);
13
+ const pointerFor = (reference, base) => {
14
+ const absolute = uri.normalize(uri.resolve(base, reference)).replace(/#$/, '');
15
+ let location = prepared.registry.get(absolute);
16
+ if (location === undefined) {
17
+ const hash = absolute.indexOf('#');
18
+ const resource = prepared.registry.get(hash < 0 ? absolute : absolute.slice(0, hash));
19
+ const fragment = hash < 0 ? '' : decodeURIComponent(absolute.slice(hash + 1));
20
+ if (resource === undefined || (fragment !== '' && !fragment.startsWith('/')))
21
+ throw new TypeError('Unsupported form reference.');
22
+ location = resource + fragment;
23
+ }
24
+ const slash = location.indexOf('/');
25
+ const index = slash < 0 ? location : location.slice(0, slash);
26
+ return `#${encodeURIComponent(`/definitions/__resource${index}${slash < 0 ? '' : location.slice(slash)}`).replace(/%2F/g, '/')}`;
27
+ };
28
+ for (const { node, base } of prepared.nodes) {
29
+ // These constructs cannot be represented faithfully by this RJSF version.
30
+ if ('$dynamicRef' in node || '$recursiveRef' in node || 'prefixItems' in node)
31
+ throw new TypeError('Unsupported form schema keyword.');
32
+ if (typeof node.$ref === 'string')
33
+ node.$ref = pointerFor(node.$ref, base);
34
+ // Every reference is now absolute within the presentation wrapper; canonical documents are untouched.
35
+ delete node.$id;
36
+ delete node.$anchor;
37
+ delete node.$dynamicAnchor;
38
+ }
39
+ if (typeof bundle.root.document === 'boolean')
40
+ throw new TypeError('A form requires an object schema.');
41
+ const view = { $schema: bundle.dialect === 'draft-07' ? 'http://json-schema.org/draft-07/schema#' : 'https://json-schema.org/draft/2020-12/schema',
42
+ definitions: Object.fromEntries(prepared.resources.map((resource, index) => [`__resource${index}`, resource.document])),
43
+ $ref: '#/definitions/__resource0' };
44
+ assertFiniteObjectRendering(view, prepared.nodes.map(({ node }) => node));
45
+ return view;
46
+ }
47
+ // RJSF eagerly expands object defaults even for absent optional properties. Array items
48
+ // are expanded only for actual elements, so recursion through arrays remains supported.
49
+ function assertFiniteObjectRendering(root, seeds) {
50
+ const active = new Set(), done = new Set();
51
+ const visit = (value) => {
52
+ if (!value || typeof value !== 'object' || Array.isArray(value))
53
+ return;
54
+ if (active.has(value))
55
+ throw new TypeError('Unsupported recursive object form schema.');
56
+ if (done.has(value))
57
+ return;
58
+ active.add(value);
59
+ const node = value;
60
+ if (typeof node.$ref === 'string') {
61
+ let target = root;
62
+ for (const segment of decodeURIComponent(node.$ref.slice(1)).slice(1).split('/')) {
63
+ target = target[segment.replace(/~1/g, '/').replace(/~0/g, '~')];
64
+ }
65
+ visit(target);
66
+ }
67
+ for (const key of ['properties', 'patternProperties', 'dependentSchemas', 'dependencies']) {
68
+ const map = node[key];
69
+ if (map && typeof map === 'object')
70
+ Object.values(map).forEach(visit);
71
+ }
72
+ for (const key of ['allOf', 'anyOf', 'oneOf'])
73
+ if (Array.isArray(node[key]))
74
+ node[key].forEach(visit);
75
+ for (const key of ['additionalProperties', 'if', 'then', 'else'])
76
+ visit(node[key]);
77
+ active.delete(value);
78
+ done.add(value);
79
+ };
80
+ visit(root);
81
+ seeds.forEach(visit);
82
+ }
83
+ /** Keep literal property names, including dots and pointer escapes, intact. */
84
+ export function fieldErrors(issues) {
85
+ const root = Object.create(null);
86
+ for (const issue of issues) {
87
+ let node = root;
88
+ const path = issue.path;
89
+ const segments = (path === null || path === void 0 ? void 0 : path.startsWith('/')) ? path.slice(1).split('/').map(s => s.replace(/~1/g, '/').replace(/~0/g, '~')) : [];
90
+ // RJSF reserves __errors; retain this diagnostic at the root rather than losing it.
91
+ if (!segments.includes('__errors'))
92
+ for (const segment of segments) {
93
+ if (!Object.hasOwn(node, segment))
94
+ Object.defineProperty(node, segment, { value: Object.create(null), enumerable: true });
95
+ node = node[segment];
96
+ }
97
+ if (!Object.hasOwn(node, '__errors'))
98
+ Object.defineProperty(node, '__errors', { value: [], enumerable: true });
99
+ node.__errors.push(issue.message);
100
+ }
101
+ return root;
102
+ }
@@ -0,0 +1,10 @@
1
+ import type { InputDiagnostic, ValidationIssue } from './schema-types.js';
2
+ export type * from './schema-types.js';
3
+ export { compileSchemaBundle } from './schema-engine.js';
4
+ export { validateSchemaInput } from './schema-compose.js';
5
+ /** Convert input diagnostics without copying raw data or changing JSON Pointer paths. */
6
+ export declare function toValidationIssues(diagnostics: readonly InputDiagnostic[]): readonly ValidationIssue[];
7
+ export type * from './source-types.js';
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 ADDED
@@ -0,0 +1,87 @@
1
+ export { compileSchemaBundle } from './schema-engine.js';
2
+ export { validateSchemaInput } from './schema-compose.js';
3
+ const messages = {
4
+ 'input-format-invalid': 'Input format is invalid.',
5
+ 'variant-unrecognized': 'Input variant is not recognized.',
6
+ 'input-not-json': 'Input must be a JSON-compatible value.',
7
+ 'schema-data-invalid': 'Value does not satisfy the schema.',
8
+ 'owner-input-invalid': 'Value does not satisfy the owner input rules.'
9
+ };
10
+ function isRecord(value) {
11
+ return value !== null && typeof value === 'object' && !Array.isArray(value);
12
+ }
13
+ function isPointer(value) {
14
+ return typeof value === 'string' && (value === '' || value.startsWith('/')) && !/~(?:[^01]|$)/u.test(value);
15
+ }
16
+ function readValidationIssue(value) {
17
+ if (!isRecord(value))
18
+ throw new TypeError();
19
+ const scope = value.scope;
20
+ if (!isRecord(scope))
21
+ throw new TypeError();
22
+ const identity = scope.identity;
23
+ if (!isRecord(identity))
24
+ throw new TypeError();
25
+ if (['ownerId', 'contractId', 'revision', 'variantId'].some(key => typeof identity[key] !== 'string')) {
26
+ throw new TypeError();
27
+ }
28
+ if ('consumerId' in scope && typeof scope.consumerId !== 'string')
29
+ throw new TypeError();
30
+ if ('resourceUri' in value && typeof value.resourceUri !== 'string')
31
+ throw new TypeError();
32
+ if ('schemaPath' in value && !isPointer(value.schemaPath))
33
+ throw new TypeError();
34
+ // Keep primitives locally so accessors cannot change them between validation and conversion.
35
+ const dataPath = value.dataPath;
36
+ const phase = value.phase;
37
+ const code = value.code;
38
+ if (!isPointer(dataPath))
39
+ throw new TypeError();
40
+ switch (phase) {
41
+ case 'decode':
42
+ if (code !== 'input-format-invalid' && code !== 'variant-unrecognized')
43
+ throw new TypeError();
44
+ break;
45
+ case 'structure':
46
+ if (code !== 'input-not-json' && code !== 'schema-data-invalid')
47
+ throw new TypeError();
48
+ if ('keyword' in value && typeof value.keyword !== 'string')
49
+ throw new TypeError();
50
+ break;
51
+ case 'semantic':
52
+ if (code !== 'owner-input-invalid' || typeof value.ruleId !== 'string')
53
+ throw new TypeError();
54
+ break;
55
+ default:
56
+ throw new TypeError();
57
+ }
58
+ return Object.freeze({ message: messages[code], path: dataPath });
59
+ }
60
+ /** Convert input diagnostics without copying raw data or changing JSON Pointer paths. */
61
+ export function toValidationIssues(diagnostics) {
62
+ try {
63
+ if (!Array.isArray(diagnostics))
64
+ throw new TypeError();
65
+ const length = diagnostics.length;
66
+ if (!Number.isSafeInteger(length) || length < 0)
67
+ throw new TypeError();
68
+ // Snapshot indexed elements before invoking diagnostic getters. Ignore input iterators.
69
+ const snapshot = [];
70
+ for (let index = 0; index < length; index++) {
71
+ if (!Object.hasOwn(diagnostics, index))
72
+ throw new TypeError();
73
+ snapshot.push(diagnostics[index]);
74
+ }
75
+ const issues = [];
76
+ for (let index = 0; index < length; index++) {
77
+ issues.push(readValidationIssue(snapshot[index]));
78
+ }
79
+ return Object.freeze(issues);
80
+ }
81
+ catch (_a) {
82
+ // Never expose an external value or a getter's exception through this boundary.
83
+ throw new TypeError('Invalid input diagnostic.');
84
+ }
85
+ }
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);
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,13 +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_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
+ 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';
16
22
  export class EditorSession {
17
23
  /** Use EditorRegistry.open() to construct sessions from a captured host snapshot. */
18
- constructor(definition, snapshot, host) {
24
+ constructor(definition, snapshot, host, isRegistered, subscribeRegistrationChanges) {
19
25
  _EditorSession_instances.add(this);
20
26
  _EditorSession_draft.set(this, void 0);
21
27
  _EditorSession_status.set(this, 'editing');
@@ -26,10 +32,68 @@ export class EditorSession {
26
32
  _EditorSession_definition.set(this, void 0);
27
33
  _EditorSession_snapshot.set(this, void 0);
28
34
  _EditorSession_host.set(this, void 0);
35
+ _EditorSession_fixedPort.set(this, void 0);
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);
41
+ __classPrivateFieldSet(this, _EditorSession_isRegistered, isRegistered, "f");
42
+ __classPrivateFieldSet(this, _EditorSession_subscribeRegistrationChanges, subscribeRegistrationChanges, "f");
29
43
  __classPrivateFieldSet(this, _EditorSession_definition, definition, "f");
30
- __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");
31
47
  __classPrivateFieldSet(this, _EditorSession_host, host, "f");
32
- __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
+ }
33
97
  }
34
98
  /** Stable instance identity remains available after the session closes. */
35
99
  get reference() {
@@ -39,6 +103,36 @@ export class EditorSession {
39
103
  __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_assertOpen).call(this);
40
104
  return cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f"));
41
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
+ }
42
136
  setDraft(draft) {
43
137
  if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'editing')
44
138
  throw new Error('The session is not editable.');
@@ -77,18 +171,30 @@ export class EditorSession {
77
171
  __classPrivateFieldSet(this, _EditorSession_error, undefined, "f");
78
172
  __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_notify).call(this);
79
173
  try {
80
- const issues = await __classPrivateFieldGet(this, _EditorSession_definition, "f").validate(cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f"));
174
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
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);
178
+ const prepared = isPreparedEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f"))
179
+ ? capturePreparedSave(__classPrivateFieldGet(this, _EditorSession_definition, "f"), cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f")) : undefined;
180
+ const issues = prepared ? (prepared.kind === 'invalid' ? prepared.issues : [])
181
+ : await __classPrivateFieldGet(this, _EditorSession_definition, "f").validate(cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f"));
81
182
  if (!Array.isArray(issues))
82
183
  throw new TypeError('validate() must return an issue array.');
83
184
  if (issues.length > 0) {
84
185
  __classPrivateFieldSet(this, _EditorSession_issues, __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_copyIssues).call(this, issues), "f");
85
186
  return { status: 'invalid', issues: __classPrivateFieldGet(this, _EditorSession_issues, "f") };
86
187
  }
87
- const changes = __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_prepareChanges).call(this, __classPrivateFieldGet(this, _EditorSession_definition, "f").createPatch(cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f")));
188
+ const changes = __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_prepareChanges).call(this, (prepared === null || prepared === void 0 ? void 0 : prepared.kind) === 'ready' ? prepared.changes
189
+ : __classPrivateFieldGet(this, _EditorSession_definition, "f").createPatch(cloneJson(__classPrivateFieldGet(this, _EditorSession_draft, "f")), __classPrivateFieldGet(this, _EditorSession_snapshot, "f")));
190
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
191
+ throw new BlockEditorConflictError('The source editor registration expired.');
88
192
  const current = __classPrivateFieldGet(this, _EditorSession_host, "f").readBlock(__classPrivateFieldGet(this, _EditorSession_snapshot, "f"));
89
193
  if (!current || !sameSnapshot(__classPrivateFieldGet(this, _EditorSession_snapshot, "f"), captureSnapshot(current, __classPrivateFieldGet(this, _EditorSession_snapshot, "f")))) {
90
194
  throw new BlockEditorConflictError();
91
195
  }
196
+ if (__classPrivateFieldGet(this, _EditorSession_isRegistered, "f") && !__classPrivateFieldGet(this, _EditorSession_isRegistered, "f").call(this))
197
+ throw new BlockEditorConflictError('The source editor registration expired.');
92
198
  if (changes.length > 0) {
93
199
  await __classPrivateFieldGet(this, _EditorSession_host, "f").commit(Object.freeze({ expected: __classPrivateFieldGet(this, _EditorSession_snapshot, "f"), changes }));
94
200
  }
@@ -122,7 +228,73 @@ export class EditorSession {
122
228
  return true;
123
229
  }
124
230
  }
125
- _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_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) {
126
298
  if (!Array.isArray(patch))
127
299
  throw new TypeError('createPatch() must return an array.');
128
300
  const seen = new Set();
@@ -138,11 +310,23 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
138
310
  if (!slot || slot.kind !== 'literal') {
139
311
  throw new TypeError('Only existing literal arguments can be changed.');
140
312
  }
141
- 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)
142
322
  changes.push(Object.freeze({ ...change }));
143
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.');
144
326
  return Object.freeze(changes);
145
327
  }, _EditorSession_copyIssues = function _EditorSession_copyIssues(issues) {
328
+ if (isFixedInputEditor(__classPrivateFieldGet(this, _EditorSession_definition, "f")))
329
+ issues = snapshotJson(issues);
146
330
  if (!Array.isArray(issues))
147
331
  throw new TypeError('Expected a validation issue array.');
148
332
  return Object.freeze(issues.map(issue => {
@@ -156,7 +340,18 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
156
340
  if (!draft || typeof draft !== 'object' || Array.isArray(draft)) {
157
341
  throw new TypeError('The editor draft must be a JSON object.');
158
342
  }
159
- 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
+ }
160
355
  }, _EditorSession_assertOpen = function _EditorSession_assertOpen() {
161
356
  if (__classPrivateFieldGet(this, _EditorSession_status, "f") !== 'editing' && __classPrivateFieldGet(this, _EditorSession_status, "f") !== 'saving') {
162
357
  throw new Error('The session is closed.');
@@ -164,6 +359,22 @@ _EditorSession_draft = new WeakMap(), _EditorSession_status = new WeakMap(), _Ed
164
359
  }, _EditorSession_finish = function _EditorSession_finish(status) {
165
360
  __classPrivateFieldSet(this, _EditorSession_status, status, "f");
166
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
+ }
167
378
  __classPrivateFieldGet(this, _EditorSession_instances, "m", _EditorSession_notify).call(this);
168
379
  try {
169
380
  __classPrivateFieldGet(this, _EditorSession_view, "f").unmount();
@@ -0,0 +1,3 @@
1
+ import type { JsonValue } from './types.js';
2
+ /** Patch only edited source ranges; unsupported lossless operations fail closed. */
3
+ export declare function patchSource(source: string, format: 'json' | 'yaml', original: JsonValue, edited: JsonValue): string;