@kubohiroya/turbowarp-extension-data-editor 0.2.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.
- package/README.md +9 -6
- package/dist/build-info.json +4 -4
- package/dist/fixed-input-branches.d.ts +12 -0
- package/dist/fixed-input-branches.js +180 -0
- package/dist/fixed-input-editor.d.ts +39 -0
- package/dist/fixed-input-editor.js +538 -0
- package/dist/fixed-input-schema.d.ts +15 -0
- package/dist/fixed-input-schema.js +21 -0
- package/dist/fixed-input-snapshot.d.ts +7 -0
- package/dist/fixed-input-snapshot.js +180 -0
- package/dist/fixed-input-types.d.ts +138 -0
- package/dist/fixed-input-types.js +23 -0
- package/dist/fixed-input-view.d.ts +14 -0
- package/dist/fixed-input-view.js +168 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/react.css +42 -0
- package/dist/react.d.ts +3 -0
- package/dist/react.js +10 -1
- package/dist/registry.d.ts +4 -0
- package/dist/registry.js +45 -7
- package/dist/rjsf.d.ts +24 -1
- package/dist/rjsf.js +22 -2
- package/dist/schema.d.ts +2 -0
- package/dist/schema.js +1 -0
- package/dist/session.d.ts +3 -1
- package/dist/session.js +205 -7
- package/dist/turbowarp/bridge.d.ts +2 -1
- package/dist/turbowarp/bridge.js +34 -5
- package/dist/turbowarp/fixed-fields.d.ts +82 -0
- package/dist/turbowarp/fixed-fields.js +311 -0
- package/dist/turbowarp/fixed-transaction.d.ts +18 -0
- package/dist/turbowarp/fixed-transaction.js +460 -0
- package/dist/turbowarp/host.d.ts +3 -8
- package/dist/turbowarp/host.js +68 -1
- package/dist/turbowarp.d.ts +4 -0
- package/dist/turbowarp.js +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/view.js +4 -0
- package/dist/webpack4/index.js +22 -5
- package/dist/webpack4/metafile.json +588 -319
- package/dist/webpack4/react.js +9 -1
- package/dist/webpack4/react.js.map +2 -2
- package/dist/webpack4/rjsf.js +249 -34
- package/dist/webpack4/rjsf.js.map +4 -4
- package/dist/webpack4/schema.js +6 -3
- package/dist/webpack4/{shared-KQOUMWJ4.js → shared-75QIWLZY.js} +1129 -1244
- package/dist/webpack4/{shared-KQOUMWJ4.js.map → shared-75QIWLZY.js.map} +4 -4
- package/dist/webpack4/shared-FYUILHED.js +1 -0
- package/dist/webpack4/shared-GQLPPRT2.js +210 -0
- package/dist/webpack4/shared-GQLPPRT2.js.map +7 -0
- package/dist/webpack4/shared-P2JBRZFP.js +2206 -0
- package/dist/webpack4/shared-P2JBRZFP.js.map +7 -0
- package/dist/webpack4/turbowarp.js +910 -9
- package/dist/webpack4/turbowarp.js.map +4 -4
- package/docs/fixed-input-contracts.md +77 -0
- package/docs/stage-2-publication.ja.md +6 -0
- package/package.json +8 -1
- package/dist/webpack4/shared-CQB3NG2A.js +0 -1
- package/dist/webpack4/shared-MRPGBJIH.js +0 -75
- package/dist/webpack4/shared-MRPGBJIH.js.map +0 -7
- package/dist/webpack4/shared-N6YQE2X6.js +0 -1029
- package/dist/webpack4/shared-N6YQE2X6.js.map +0 -7
- /package/dist/webpack4/{shared-CQB3NG2A.js.map → shared-FYUILHED.js.map} +0 -0
package/dist/registry.js
CHANGED
|
@@ -3,7 +3,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
3
3
|
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");
|
|
4
4
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
5
|
};
|
|
6
|
-
var _EditorRegistry_instances, _EditorRegistry_editors, _EditorRegistry_opcodes, _EditorRegistry_changes, _EditorRegistry_register, _EditorRegistry_notifyChanges;
|
|
6
|
+
var _EditorRegistry_instances, _EditorRegistry_editors, _EditorRegistry_opcodes, _EditorRegistry_fixedDeclarations, _EditorRegistry_changes, _EditorRegistry_register, _EditorRegistry_notifyChanges;
|
|
7
7
|
import { captureReference, captureSnapshot } from './data.js';
|
|
8
8
|
import { EditorSession } from './session.js';
|
|
9
9
|
import { DescendantSession } from './descendants.js';
|
|
@@ -11,14 +11,20 @@ import { supportsDescendantEditing } from './descendant-types.js';
|
|
|
11
11
|
import { captureSubtree, descendantLimits } from './subtree.js';
|
|
12
12
|
import { EDITOR_API_VERSION } from './types.js';
|
|
13
13
|
import { isPreparedEditor } from './prepared-save.js';
|
|
14
|
+
import { isFixedInputEditor, captureFixedInputEditorDefinition } from './fixed-input-editor.js';
|
|
15
|
+
import { captureFixedInputDeclaration, captureFixedSnapshot } from './fixed-input-snapshot.js';
|
|
16
|
+
import { supportsFixedInputEditing } from './fixed-input-types.js';
|
|
14
17
|
export class EditorRegistry {
|
|
15
18
|
constructor() {
|
|
16
19
|
_EditorRegistry_instances.add(this);
|
|
17
20
|
_EditorRegistry_editors.set(this, new Map());
|
|
18
21
|
_EditorRegistry_opcodes.set(this, new Map());
|
|
22
|
+
_EditorRegistry_fixedDeclarations.set(this, new Map());
|
|
19
23
|
_EditorRegistry_changes.set(this, new Set());
|
|
20
24
|
}
|
|
21
25
|
register(definition) {
|
|
26
|
+
if (isFixedInputEditor(definition))
|
|
27
|
+
throw new TypeError('Fixed input editors require registerFixed().');
|
|
22
28
|
if (isPreparedEditor(definition))
|
|
23
29
|
throw new TypeError('Prepared editors require registerPrepared().');
|
|
24
30
|
return __classPrivateFieldGet(this, _EditorRegistry_instances, "m", _EditorRegistry_register).call(this, definition);
|
|
@@ -29,6 +35,9 @@ export class EditorRegistry {
|
|
|
29
35
|
}
|
|
30
36
|
return __classPrivateFieldGet(this, _EditorRegistry_instances, "m", _EditorRegistry_register).call(this, definition);
|
|
31
37
|
}
|
|
38
|
+
registerFixed(definition) {
|
|
39
|
+
return __classPrivateFieldGet(this, _EditorRegistry_instances, "m", _EditorRegistry_register).call(this, captureFixedInputEditorDefinition(definition));
|
|
40
|
+
}
|
|
32
41
|
resolve(opcode) {
|
|
33
42
|
const entry = __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(opcode);
|
|
34
43
|
if (!entry)
|
|
@@ -38,15 +47,37 @@ export class EditorRegistry {
|
|
|
38
47
|
opcodes: entry.opcodes, editableArguments: entry.editableArguments
|
|
39
48
|
});
|
|
40
49
|
}
|
|
50
|
+
/** Stable, callback-free authority for this exact registration, never caller metadata. */
|
|
51
|
+
resolveFixed(opcode) {
|
|
52
|
+
const entry = __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(opcode);
|
|
53
|
+
return entry ? __classPrivateFieldGet(this, _EditorRegistry_fixedDeclarations, "f").get(entry) : undefined;
|
|
54
|
+
}
|
|
41
55
|
open(reference, host) {
|
|
42
56
|
const capturedReference = captureReference(reference);
|
|
43
57
|
const live = host.readBlock(capturedReference);
|
|
44
58
|
if (!live)
|
|
45
59
|
return undefined;
|
|
60
|
+
const entry = __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(live.opcode);
|
|
61
|
+
if (!entry) {
|
|
62
|
+
// Preserve legacy snapshot validation even when no editor is registered.
|
|
63
|
+
captureSnapshot(live, capturedReference);
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (isFixedInputEditor(entry)) {
|
|
67
|
+
if (!supportsFixedInputEditing(host))
|
|
68
|
+
return undefined;
|
|
69
|
+
const fixed = host.fixedInputs.readBlock(capturedReference, entry);
|
|
70
|
+
if (!fixed || fixed.opcode !== live.opcode)
|
|
71
|
+
return undefined;
|
|
72
|
+
const snapshot = captureFixedSnapshot(fixed, capturedReference, entry);
|
|
73
|
+
return new EditorSession(entry, snapshot, host, () => __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(snapshot.opcode) === entry, listener => {
|
|
74
|
+
__classPrivateFieldGet(this, _EditorRegistry_changes, "f").add(listener);
|
|
75
|
+
return () => { __classPrivateFieldGet(this, _EditorRegistry_changes, "f").delete(listener); };
|
|
76
|
+
});
|
|
77
|
+
}
|
|
46
78
|
const snapshot = captureSnapshot(live, capturedReference);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
? () => __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(snapshot.opcode) === entry : undefined) : undefined;
|
|
79
|
+
return new EditorSession(entry, snapshot, host, isPreparedEditor(entry)
|
|
80
|
+
? () => __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(snapshot.opcode) === entry : undefined);
|
|
50
81
|
}
|
|
51
82
|
openDescendants(reference, host, limits) {
|
|
52
83
|
if (!supportsDescendantEditing(host))
|
|
@@ -58,15 +89,19 @@ export class EditorRegistry {
|
|
|
58
89
|
if (!live)
|
|
59
90
|
return undefined;
|
|
60
91
|
const captured = captureSubtree(live, capturedReference, resolvedLimits);
|
|
61
|
-
|
|
92
|
+
const root = __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(captured.snapshot.nodes[0].block.opcode);
|
|
93
|
+
if (!root || isFixedInputEditor(root))
|
|
62
94
|
return undefined;
|
|
63
|
-
return new DescendantSession(captured, port, opcode =>
|
|
95
|
+
return new DescendantSession(captured, port, opcode => {
|
|
96
|
+
const entry = __classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").get(opcode);
|
|
97
|
+
return entry && !isFixedInputEditor(entry) ? entry : undefined;
|
|
98
|
+
}, listener => {
|
|
64
99
|
__classPrivateFieldGet(this, _EditorRegistry_changes, "f").add(listener);
|
|
65
100
|
return () => { __classPrivateFieldGet(this, _EditorRegistry_changes, "f").delete(listener); };
|
|
66
101
|
}, resolvedLimits);
|
|
67
102
|
}
|
|
68
103
|
}
|
|
69
|
-
_EditorRegistry_editors = new WeakMap(), _EditorRegistry_opcodes = new WeakMap(), _EditorRegistry_changes = new WeakMap(), _EditorRegistry_instances = new WeakSet(), _EditorRegistry_register = function _EditorRegistry_register(definition) {
|
|
104
|
+
_EditorRegistry_editors = new WeakMap(), _EditorRegistry_opcodes = new WeakMap(), _EditorRegistry_fixedDeclarations = new WeakMap(), _EditorRegistry_changes = new WeakMap(), _EditorRegistry_instances = new WeakSet(), _EditorRegistry_register = function _EditorRegistry_register(definition) {
|
|
70
105
|
if (definition.apiVersion !== EDITOR_API_VERSION)
|
|
71
106
|
throw new TypeError('Unsupported editor API version.');
|
|
72
107
|
if (!/^[a-z0-9]+$/i.test(definition.extensionId) ||
|
|
@@ -98,6 +133,8 @@ _EditorRegistry_editors = new WeakMap(), _EditorRegistry_opcodes = new WeakMap()
|
|
|
98
133
|
opcodes: Object.freeze([...definition.opcodes]),
|
|
99
134
|
editableArguments: Object.freeze([...definition.editableArguments])
|
|
100
135
|
});
|
|
136
|
+
if (isFixedInputEditor(entry))
|
|
137
|
+
__classPrivateFieldGet(this, _EditorRegistry_fixedDeclarations, "f").set(entry, captureFixedInputDeclaration(entry));
|
|
101
138
|
__classPrivateFieldGet(this, _EditorRegistry_editors, "f").set(key, entry);
|
|
102
139
|
for (const opcode of entry.opcodes)
|
|
103
140
|
__classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").set(opcode, entry);
|
|
@@ -108,6 +145,7 @@ _EditorRegistry_editors = new WeakMap(), _EditorRegistry_opcodes = new WeakMap()
|
|
|
108
145
|
__classPrivateFieldGet(this, _EditorRegistry_editors, "f").delete(key);
|
|
109
146
|
for (const opcode of entry.opcodes)
|
|
110
147
|
__classPrivateFieldGet(this, _EditorRegistry_opcodes, "f").delete(opcode);
|
|
148
|
+
__classPrivateFieldGet(this, _EditorRegistry_fixedDeclarations, "f").delete(entry);
|
|
111
149
|
__classPrivateFieldGet(this, _EditorRegistry_instances, "m", _EditorRegistry_notifyChanges).call(this);
|
|
112
150
|
};
|
|
113
151
|
}, _EditorRegistry_notifyChanges = function _EditorRegistry_notifyChanges() {
|
package/dist/rjsf.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import type { FixedInputMessageSource } from './fixed-input-view.js';
|
|
2
|
+
export type { FixedInputViewMessages, FixedInputMessageSource } from './fixed-input-view.js';
|
|
3
|
+
import type { FixedInputEditorOptions } from './fixed-input-editor.js';
|
|
4
|
+
export { createFixedInputEditor } from './fixed-input-editor.js';
|
|
5
|
+
export type { FixedInputEditorOptions, FixedInputBinding, FixedInputBranchPolicy } from './fixed-input-editor.js';
|
|
6
|
+
export type * from './fixed-input-types.js';
|
|
1
7
|
import type { SourceEditorOptions } from './source-types.js';
|
|
2
8
|
export { createSourceEditor } from './source-editor.js';
|
|
3
9
|
export type * from './source-types.js';
|
|
@@ -35,6 +41,7 @@ export interface BlockEditorRegistrationAPI {
|
|
|
35
41
|
registerSchema(definition: SchemaEditorOptions): () => void;
|
|
36
42
|
registerSchemaBundle?<C>(definition: SchemaBundleEditorOptions<C>): () => void;
|
|
37
43
|
registerSourceEditor?<C = null>(definition: SourceEditorOptions<C>): () => void;
|
|
44
|
+
registerFixedInputEditor?<C = null>(definition: FixedInputEditorOptions<C>): () => void;
|
|
38
45
|
}
|
|
39
46
|
/** Capability guaranteed by the service factory, optional on a legacy host-supplied API. */
|
|
40
47
|
export interface SchemaBundleBlockEditorRegistrationAPI extends BlockEditorRegistrationAPI {
|
|
@@ -44,14 +51,30 @@ export interface SchemaBundleBlockEditorRegistrationAPI extends BlockEditorRegis
|
|
|
44
51
|
export interface SourceBlockEditorRegistrationAPI extends SchemaBundleBlockEditorRegistrationAPI {
|
|
45
52
|
registerSourceEditor<C = null>(definition: SourceEditorOptions<C>): () => void;
|
|
46
53
|
}
|
|
54
|
+
export interface FixedBlockEditorRegistrationAPI extends SourceBlockEditorRegistrationAPI {
|
|
55
|
+
registerFixedInputEditor<C = null>(definition: FixedInputEditorOptions<C>): () => void;
|
|
56
|
+
}
|
|
47
57
|
export interface BlockEditorService {
|
|
48
58
|
readonly registry: EditorRegistry;
|
|
49
59
|
readonly api: BlockEditorRegistrationAPI;
|
|
50
60
|
subscribe(listener: () => void): () => void;
|
|
51
61
|
}
|
|
52
62
|
/** A host owns the service's lifetime; this module never stores VM or workspace instances. */
|
|
53
|
-
export declare function createBlockEditorService(
|
|
63
|
+
export declare function createBlockEditorService(options: {
|
|
64
|
+
readonly fixedInputs: true;
|
|
65
|
+
readonly fixedInputMessages?: FixedInputMessageSource;
|
|
66
|
+
}): BlockEditorService & {
|
|
67
|
+
readonly api: FixedBlockEditorRegistrationAPI;
|
|
68
|
+
};
|
|
69
|
+
export declare function createBlockEditorService(options?: {
|
|
70
|
+
readonly fixedInputs?: false;
|
|
71
|
+
readonly fixedInputMessages?: FixedInputMessageSource;
|
|
72
|
+
}): BlockEditorService & {
|
|
54
73
|
readonly api: SourceBlockEditorRegistrationAPI;
|
|
55
74
|
};
|
|
75
|
+
export declare function createBlockEditorService(options: {
|
|
76
|
+
readonly fixedInputs?: boolean;
|
|
77
|
+
readonly fixedInputMessages?: FixedInputMessageSource;
|
|
78
|
+
}): BlockEditorService;
|
|
56
79
|
/** Build an editor with JSON/YAML serialization, schema validation and the standard RJSF body. */
|
|
57
80
|
export declare function createSchemaEditor(options: SchemaEditorOptions): EditorDefinition;
|
package/dist/rjsf.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { createSourceEditor } from './source-editor.js';
|
|
3
|
+
import { createFixedInputEditor } from './fixed-input-editor.js';
|
|
4
|
+
import { captureFixedInputMessages, resolveFixedInputMessages, mountFixedInputView } from './fixed-input-view.js';
|
|
5
|
+
export { createFixedInputEditor } from './fixed-input-editor.js';
|
|
3
6
|
export { createSourceEditor } from './source-editor.js';
|
|
4
7
|
import * as ReactDOM from 'react-dom';
|
|
5
8
|
import * as RjsfCore from '@rjsf/core';
|
|
@@ -65,13 +68,30 @@ export function createSchemaBundleEditor(options) {
|
|
|
65
68
|
...(format === undefined ? {} : { format }), ...(uiSchema === undefined ? {} : { uiSchema }),
|
|
66
69
|
...(validateData === undefined ? {} : { validateData }) }, { issuesFor, dialect: result.validator.dialect });
|
|
67
70
|
}
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
export function createBlockEditorService(options) {
|
|
72
|
+
if ((options === null || options === void 0 ? void 0 : options.fixedInputs) !== undefined && typeof options.fixedInputs !== 'boolean')
|
|
73
|
+
throw new TypeError('Invalid fixed input capability option.');
|
|
74
|
+
const messageSource = options === null || options === void 0 ? void 0 : options.fixedInputMessages;
|
|
75
|
+
const fixedMessages = typeof messageSource === 'function' ? messageSource : captureFixedInputMessages(messageSource);
|
|
70
76
|
const registry = new EditorRegistry();
|
|
71
77
|
const listeners = new Set();
|
|
72
78
|
const notify = () => { for (const listener of [...listeners])
|
|
73
79
|
listener(); };
|
|
80
|
+
const fixed = (options === null || options === void 0 ? void 0 : options.fixedInputs) === true ? {
|
|
81
|
+
registerFixedInputEditor: (definition) => {
|
|
82
|
+
const fixedDefinition = createFixedInputEditor(definition);
|
|
83
|
+
const remove = registry.registerFixed({ ...fixedDefinition, mount: (container, context) => mountFixedInputView(container, context, resolveFixedInputMessages(fixedMessages)) });
|
|
84
|
+
notify();
|
|
85
|
+
let active = true;
|
|
86
|
+
return () => { if (active) {
|
|
87
|
+
active = false;
|
|
88
|
+
remove();
|
|
89
|
+
notify();
|
|
90
|
+
} };
|
|
91
|
+
}
|
|
92
|
+
} : {};
|
|
74
93
|
const api = Object.freeze({
|
|
94
|
+
...fixed,
|
|
75
95
|
apiVersion: EDITOR_API_VERSION,
|
|
76
96
|
register: (definition) => {
|
|
77
97
|
const custom = definition;
|
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
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,
|
|
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,
|
|
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(),
|
|
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 (
|
|
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
|
-
|
|
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;
|
package/dist/turbowarp/bridge.js
CHANGED
|
@@ -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
|
|
7
|
-
registry.
|
|
8
|
-
const
|
|
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,6 +92,7 @@ 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);
|
|
76
98
|
if (typeof session.getNodes === 'function') {
|
|
@@ -88,6 +110,7 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
|
|
|
88
110
|
onError(error);
|
|
89
111
|
activeSession = createBlockEditorErrorSession(reference, error);
|
|
90
112
|
openingSnapshot = null;
|
|
113
|
+
openingFixedDeclaration = null;
|
|
91
114
|
onOpen(activeSession);
|
|
92
115
|
}
|
|
93
116
|
};
|
|
@@ -137,7 +160,13 @@ const createBlockEditorBridge = ({ ScratchBlocks, workspace, vm, service, label,
|
|
|
137
160
|
};
|
|
138
161
|
const unregister = service.subscribe(() => {
|
|
139
162
|
// Aggregate sessions observe relevant registry changes themselves.
|
|
140
|
-
if (
|
|
163
|
+
if (openingFixedDeclaration && activeSession) {
|
|
164
|
+
if (service.registry.resolveFixed(openingSnapshot.opcode) !== openingFixedDeclaration) {
|
|
165
|
+
host.invalidate();
|
|
166
|
+
endSession();
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else if (!activeSession || typeof activeSession.getNodes !== 'function') {
|
|
141
170
|
host.invalidate();
|
|
142
171
|
endSession();
|
|
143
172
|
}
|