@baron1996/klinecharts-runtime 0.5.1 → 0.7.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 CHANGED
@@ -4,7 +4,7 @@ Browser editing runtime and standard annotation toolbar for deterministic KLineC
4
4
  ChartScene files.
5
5
 
6
6
  ```bash
7
- npm install --save-exact @baron1996/kline-scene-schema@0.5.1 @baron1996/klinecharts-runtime@0.5.1
7
+ npm install --save-exact @baron1996/kline-scene-schema@0.6.0 @baron1996/klinecharts-runtime@0.7.1
8
8
  ```
9
9
 
10
10
  ```ts
@@ -45,3 +45,53 @@ Runtime `0.2.0` events are structured-cloneable pure data with
45
45
  `sceneVersion: 1` and `runtimeVersion: '0.2.0'`. Measurement scenes persist only
46
46
  their two data-coordinate endpoints, styles, and opaque metadata; displayed absolute
47
47
  and percentage changes are derived.
48
+
49
+ ## Cross-period Drawing orchestration
50
+
51
+ Cross-period Drawing uses the existing `DrawableWorkspaceRuntime` in explicit
52
+ `host-confirmed` mode. The coordinator binds a host-owned stable instrument key to
53
+ the Workspace `scopeKey`, loads a complete replacement Scene through a host port,
54
+ and commits a Drawing candidate only after the persistence receipt returns the exact
55
+ Runtime canonical hash.
56
+
57
+ ```ts
58
+ import {
59
+ createCrossPeriodDrawingCoordinator,
60
+ createDrawableWorkspaceRuntime,
61
+ } from '@baron1996/klinecharts-runtime';
62
+
63
+ const runtime = await createDrawableWorkspaceRuntime(container, loadedWorkspace, {
64
+ commitMode: 'host-confirmed',
65
+ });
66
+
67
+ const coordinator = createCrossPeriodDrawingCoordinator(
68
+ runtime,
69
+ {
70
+ instrumentKey: 'CN:600519',
71
+ scopeKey: loadedWorkspace.drawings.scopeKey,
72
+ },
73
+ {
74
+ initialRevision: loadedRevision,
75
+ async loadScene({ binding, period, currentWorkspace }) {
76
+ // The host assembles a complete Scene. Financial market data must come
77
+ // through fxxking-data.
78
+ return hostSceneLoader.load({ binding, period, currentWorkspace });
79
+ },
80
+ async persistCandidate(request) {
81
+ // owner, permissions, audit and database transactions stay in the host.
82
+ return drawingRepository.compareAndSet(request);
83
+ },
84
+ },
85
+ );
86
+
87
+ await coordinator.switchPeriod({ type: 'week', span: 1 });
88
+ await coordinator.waitForIdle();
89
+
90
+ coordinator.destroy();
91
+ runtime.destroy();
92
+ ```
93
+
94
+ The coordinator never derives `scopeKey` from `scene.symbol.ticker`, never accesses
95
+ the KLineCharts `Chart`, and never converts legacy `ChartScene.overlays` into a
96
+ Workspace. A Scene switch changes only `workspace.scene`; the confirmed
97
+ `DrawingDocument` remains byte-identical.
@@ -0,0 +1,110 @@
1
+ import type { ChartScene, DrawableWorkspaceDocument, DrawingDocument, Period, TimeSeriesScene } from '@baron1996/kline-scene-schema';
2
+ import type { WorkspaceDrawingOperation, WorkspaceRuntimeListener } from '../drawing/workspace-events.js';
3
+ export type CrossPeriodDrawingState = 'ready' | 'switching-period' | 'persisting-drawing' | 'terminal-error' | 'destroyed';
4
+ export type CrossPeriodDrawingErrorCode = 'CROSS_PERIOD_INVALID_BINDING' | 'CROSS_PERIOD_SCOPE_MISMATCH' | 'CROSS_PERIOD_RUNTIME_MODE_UNSUPPORTED' | 'CROSS_PERIOD_OPERATION_IN_PROGRESS' | 'CROSS_PERIOD_RUNTIME_DESTROYED' | 'CROSS_PERIOD_PERSISTENCE_FAILED' | 'CROSS_PERIOD_PERSISTENCE_HASH_MISMATCH' | 'CROSS_PERIOD_COMMIT_AFTER_PERSIST_FAILED' | 'CROSS_PERIOD_CANDIDATE_RESTORE_FAILED' | 'CROSS_PERIOD_SCENE_PERIOD_MISMATCH' | 'CROSS_PERIOD_SCENE_SWITCH_FAILED';
5
+ export declare class CrossPeriodDrawingError extends Error {
6
+ readonly code: CrossPeriodDrawingErrorCode;
7
+ readonly path: string;
8
+ constructor(code: CrossPeriodDrawingErrorCode, path: string, message: string);
9
+ }
10
+ export interface CrossPeriodInstrumentBinding {
11
+ /** 宿主提供的稳定标的身份;不得由 ticker 或展示名称推断。 */
12
+ readonly instrumentKey: string;
13
+ /** 与 DrawingDocument.scopeKey 一对一绑定的不透明范围键。 */
14
+ readonly scopeKey: string;
15
+ }
16
+ export type CrossPeriodRevision = string | null;
17
+ export interface CrossPeriodSceneLoadRequest {
18
+ readonly binding: CrossPeriodInstrumentBinding;
19
+ readonly period: Period;
20
+ readonly currentWorkspace: DrawableWorkspaceDocument;
21
+ }
22
+ export type CrossPeriodSceneLoader = (request: CrossPeriodSceneLoadRequest) => Promise<ChartScene | TimeSeriesScene>;
23
+ export interface CrossPeriodDrawingPersistenceRequest {
24
+ readonly binding: CrossPeriodInstrumentBinding;
25
+ readonly requestId: string;
26
+ readonly operation: WorkspaceDrawingOperation;
27
+ readonly canonicalHash: string;
28
+ readonly idempotencyKey: string;
29
+ readonly expectedRevision: CrossPeriodRevision;
30
+ readonly candidateDocument: DrawingDocument;
31
+ readonly candidateWorkspace: DrawableWorkspaceDocument;
32
+ }
33
+ export interface CrossPeriodDrawingPersistenceReceipt {
34
+ readonly canonicalHash: string;
35
+ readonly revision: CrossPeriodRevision;
36
+ }
37
+ export type CrossPeriodDrawingPersistencePort = (request: CrossPeriodDrawingPersistenceRequest) => Promise<CrossPeriodDrawingPersistenceReceipt>;
38
+ /**
39
+ * 跨周期层使用的最小 Workspace Runtime 端口。
40
+ * 端口只含公共文档与事务操作,不暴露 Adapter、Chart 或投影实现。
41
+ */
42
+ export interface CrossPeriodWorkspaceRuntimePort {
43
+ readonly commitMode: 'immediate' | 'host-confirmed';
44
+ exportWorkspace(): DrawableWorkspaceDocument;
45
+ replaceScene(scene: ChartScene | TimeSeriesScene): ChartScene | TimeSeriesScene;
46
+ commitDrawingChange(requestId: string, canonicalHash: string): boolean;
47
+ rejectDrawingChange(requestId: string): boolean;
48
+ subscribe(listener: WorkspaceRuntimeListener): () => void;
49
+ }
50
+ export interface CrossPeriodDrawingCoordinatorOptions {
51
+ readonly initialRevision: CrossPeriodRevision;
52
+ readonly loadScene: CrossPeriodSceneLoader;
53
+ readonly persistCandidate: CrossPeriodDrawingPersistencePort;
54
+ readonly onEvent?: CrossPeriodDrawingCoordinatorListener;
55
+ }
56
+ export type CrossPeriodDrawingCoordinatorEvent = {
57
+ readonly type: 'state-changed';
58
+ readonly state: CrossPeriodDrawingState;
59
+ } | {
60
+ readonly type: 'drawing-persistence-started';
61
+ readonly requestId: string;
62
+ readonly canonicalHash: string;
63
+ readonly expectedRevision: CrossPeriodRevision;
64
+ } | {
65
+ readonly type: 'drawing-persistence-committed';
66
+ readonly requestId: string;
67
+ readonly canonicalHash: string;
68
+ readonly revision: CrossPeriodRevision;
69
+ } | {
70
+ readonly type: 'drawing-persistence-rejected';
71
+ readonly requestId: string;
72
+ readonly canonicalHash: string;
73
+ readonly code: CrossPeriodDrawingErrorCode;
74
+ readonly message: string;
75
+ } | {
76
+ readonly type: 'period-switch-started';
77
+ readonly period: Period;
78
+ } | {
79
+ readonly type: 'period-switch-completed';
80
+ readonly period: Period;
81
+ readonly scene: ChartScene | TimeSeriesScene;
82
+ } | {
83
+ readonly type: 'period-switch-failed';
84
+ readonly period: Period;
85
+ readonly code: CrossPeriodDrawingErrorCode;
86
+ readonly message: string;
87
+ } | {
88
+ readonly type: 'terminal-error';
89
+ readonly code: CrossPeriodDrawingErrorCode;
90
+ readonly message: string;
91
+ } | {
92
+ readonly type: 'destroyed';
93
+ };
94
+ export type CrossPeriodDrawingCoordinatorListener = (event: CrossPeriodDrawingCoordinatorEvent) => void;
95
+ /**
96
+ * 只负责编排 scope、周期切换和宿主持久化;所有画线事实与事务仍由 Workspace Runtime 权威管理。
97
+ */
98
+ export declare class CrossPeriodDrawingCoordinator {
99
+ #private;
100
+ constructor(runtime: CrossPeriodWorkspaceRuntimePort, binding: CrossPeriodInstrumentBinding, options: CrossPeriodDrawingCoordinatorOptions);
101
+ get state(): CrossPeriodDrawingState;
102
+ get currentRevision(): CrossPeriodRevision;
103
+ get instrumentBinding(): CrossPeriodInstrumentBinding;
104
+ subscribe(listener: CrossPeriodDrawingCoordinatorListener): () => void;
105
+ switchPeriod(period: Period): Promise<ChartScene | TimeSeriesScene>;
106
+ waitForIdle(): Promise<void>;
107
+ destroy(): void;
108
+ }
109
+ export declare function createCrossPeriodDrawingCoordinator(runtime: CrossPeriodWorkspaceRuntimePort, binding: CrossPeriodInstrumentBinding, options: CrossPeriodDrawingCoordinatorOptions): CrossPeriodDrawingCoordinator;
110
+ //# sourceMappingURL=coordinator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator.d.ts","sourceRoot":"","sources":["../../src/cross-period/coordinator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,328 @@
1
+ import { parseDrawableWorkspaceDocument, serializeCanonicalDrawingDocument, } from '@baron1996/kline-scene-schema';
2
+ import { deepFreeze } from '../drawing/workspace-events.js';
3
+ export class CrossPeriodDrawingError extends Error {
4
+ code;
5
+ path;
6
+ constructor(code, path, message) {
7
+ super(message);
8
+ this.name = 'CrossPeriodDrawingError';
9
+ this.code = code;
10
+ this.path = path;
11
+ }
12
+ }
13
+ function assertBinding(binding) {
14
+ if (typeof binding.instrumentKey !== 'string' ||
15
+ binding.instrumentKey.length === 0 ||
16
+ binding.instrumentKey.length > 256) {
17
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_INVALID_BINDING', '/instrumentKey', 'instrumentKey must be a non-empty string with at most 256 characters.');
18
+ }
19
+ if (typeof binding.scopeKey !== 'string' ||
20
+ binding.scopeKey.length === 0 ||
21
+ binding.scopeKey.length > 256) {
22
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_INVALID_BINDING', '/scopeKey', 'scopeKey must be a non-empty string with at most 256 characters.');
23
+ }
24
+ }
25
+ function sameBytes(left, right) {
26
+ if (left.byteLength !== right.byteLength) {
27
+ return false;
28
+ }
29
+ for (let index = 0; index < left.byteLength; index += 1) {
30
+ if (left[index] !== right[index]) {
31
+ return false;
32
+ }
33
+ }
34
+ return true;
35
+ }
36
+ function errorMessage(error) {
37
+ return error instanceof Error ? error.message : String(error);
38
+ }
39
+ function idempotencyKey(binding, canonicalHash) {
40
+ return [
41
+ 'cross-period-drawing',
42
+ encodeURIComponent(binding.scopeKey),
43
+ canonicalHash,
44
+ ].join(':');
45
+ }
46
+ /**
47
+ * 只负责编排 scope、周期切换和宿主持久化;所有画线事实与事务仍由 Workspace Runtime 权威管理。
48
+ */
49
+ export class CrossPeriodDrawingCoordinator {
50
+ /** 唯一 Workspace 事务入口;不包含 Adapter 或 Chart。 */
51
+ #runtime;
52
+ /** 宿主显式提供且全生命周期不可变的标的范围绑定。 */
53
+ #binding;
54
+ /** 行情 Scene 加载与持久化副作用均通过宿主端口注入。 */
55
+ #options;
56
+ #listeners = new Set();
57
+ /** 用于 waitForIdle 覆盖 Scene 加载和异步 Drawing 确认。 */
58
+ #pendingOperations = new Set();
59
+ #unsubscribeRuntime;
60
+ /** 编排状态与 DrawingSessionController 状态相互独立,不取代其权威。 */
61
+ #state = 'ready';
62
+ /** 最近一次成功持久化并完成 Runtime commit 后的宿主 revision。 */
63
+ #revision;
64
+ constructor(runtime, binding, options) {
65
+ assertBinding(binding);
66
+ if (runtime.commitMode !== 'host-confirmed') {
67
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_RUNTIME_MODE_UNSUPPORTED', '/commitMode', 'Cross-period persistence requires a host-confirmed Workspace Runtime.');
68
+ }
69
+ this.#assertWorkspaceScope(runtime.exportWorkspace(), binding);
70
+ this.#runtime = runtime;
71
+ this.#binding = structuredClone(binding);
72
+ this.#options = options;
73
+ this.#revision = options.initialRevision;
74
+ if (options.onEvent !== undefined) {
75
+ this.#listeners.add(options.onEvent);
76
+ }
77
+ this.#unsubscribeRuntime = runtime.subscribe((event) => this.#onWorkspaceEvent(event));
78
+ }
79
+ get state() {
80
+ return this.#state;
81
+ }
82
+ get currentRevision() {
83
+ return this.#revision;
84
+ }
85
+ get instrumentBinding() {
86
+ return structuredClone(this.#binding);
87
+ }
88
+ subscribe(listener) {
89
+ this.#assertUsable();
90
+ this.#listeners.add(listener);
91
+ return () => {
92
+ this.#listeners.delete(listener);
93
+ };
94
+ }
95
+ switchPeriod(period) {
96
+ this.#assertReady();
97
+ const requestedPeriod = structuredClone(period);
98
+ this.#setState('switching-period');
99
+ const operation = this.#performPeriodSwitch(requestedPeriod);
100
+ this.#track(operation.then(() => undefined, () => undefined));
101
+ return operation;
102
+ }
103
+ async waitForIdle() {
104
+ while (this.#pendingOperations.size > 0) {
105
+ await Promise.all([...this.#pendingOperations]);
106
+ }
107
+ }
108
+ destroy() {
109
+ if (this.#state === 'destroyed') {
110
+ return;
111
+ }
112
+ if (this.#state === 'terminal-error') {
113
+ this.#unsubscribeRuntime();
114
+ this.#state = 'destroyed';
115
+ this.#emit({ type: 'destroyed' });
116
+ this.#listeners.clear();
117
+ return;
118
+ }
119
+ if (this.#state !== 'ready' || this.#pendingOperations.size > 0) {
120
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_OPERATION_IN_PROGRESS', '/', 'Cross-period coordinator cannot be destroyed while an operation is pending.');
121
+ }
122
+ this.#unsubscribeRuntime();
123
+ this.#state = 'destroyed';
124
+ this.#emit({ type: 'destroyed' });
125
+ this.#listeners.clear();
126
+ }
127
+ async #performPeriodSwitch(period) {
128
+ this.#emit({ type: 'period-switch-started', period: structuredClone(period) });
129
+ try {
130
+ const before = this.#runtime.exportWorkspace();
131
+ this.#assertWorkspaceScope(before, this.#binding);
132
+ const drawingBytes = serializeCanonicalDrawingDocument(before.drawings);
133
+ const scene = await this.#options.loadScene({
134
+ binding: structuredClone(this.#binding),
135
+ period: structuredClone(period),
136
+ currentWorkspace: structuredClone(before),
137
+ });
138
+ if (this.#state !== 'switching-period') {
139
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_OPERATION_IN_PROGRESS', '/', 'Period switching was interrupted by another coordinator state.');
140
+ }
141
+ if (scene.period.type !== period.type ||
142
+ scene.period.span !== period.span) {
143
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_SCENE_PERIOD_MISMATCH', '/scene/period', 'The loaded Scene period does not match the requested period.');
144
+ }
145
+ const applied = this.#runtime.replaceScene(scene);
146
+ const after = this.#runtime.exportWorkspace();
147
+ this.#assertWorkspaceScope(after, this.#binding);
148
+ if (!sameBytes(drawingBytes, serializeCanonicalDrawingDocument(after.drawings))) {
149
+ throw this.#enterTerminalError('CROSS_PERIOD_SCENE_SWITCH_FAILED', 'Period switching changed the confirmed DrawingDocument.');
150
+ }
151
+ this.#emit({
152
+ type: 'period-switch-completed',
153
+ period: structuredClone(period),
154
+ scene: structuredClone(applied),
155
+ });
156
+ return structuredClone(applied);
157
+ }
158
+ catch (error) {
159
+ const normalized = error instanceof CrossPeriodDrawingError
160
+ ? error
161
+ : new CrossPeriodDrawingError('CROSS_PERIOD_SCENE_SWITCH_FAILED', '/scene', errorMessage(error));
162
+ this.#emit({
163
+ type: 'period-switch-failed',
164
+ period: structuredClone(period),
165
+ code: normalized.code,
166
+ message: normalized.message,
167
+ });
168
+ throw normalized;
169
+ }
170
+ finally {
171
+ if (this.#state === 'switching-period') {
172
+ this.#setState('ready');
173
+ }
174
+ }
175
+ }
176
+ #onWorkspaceEvent(event) {
177
+ if (event.type !== 'drawing-candidate' ||
178
+ this.#state === 'destroyed' ||
179
+ this.#state === 'terminal-error') {
180
+ return;
181
+ }
182
+ if (this.#state !== 'ready') {
183
+ const rejection = Promise.resolve().then(() => {
184
+ this.#rejectCandidate(event, new CrossPeriodDrawingError('CROSS_PERIOD_OPERATION_IN_PROGRESS', '/drawings', 'A Drawing candidate was received while cross-period orchestration was busy.'));
185
+ });
186
+ this.#track(rejection);
187
+ return;
188
+ }
189
+ this.#setState('persisting-drawing');
190
+ const persistence = Promise.resolve().then(() => this.#persistCandidate(event));
191
+ this.#track(persistence);
192
+ }
193
+ async #persistCandidate(event) {
194
+ this.#emit({
195
+ type: 'drawing-persistence-started',
196
+ requestId: event.requestId,
197
+ canonicalHash: event.canonicalHash,
198
+ expectedRevision: this.#revision,
199
+ });
200
+ let receipt;
201
+ try {
202
+ const candidateWorkspace = this.#candidateWorkspace(event.candidateDocument);
203
+ receipt = await this.#options.persistCandidate({
204
+ binding: structuredClone(this.#binding),
205
+ requestId: event.requestId,
206
+ operation: event.operation,
207
+ canonicalHash: event.canonicalHash,
208
+ idempotencyKey: idempotencyKey(this.#binding, event.canonicalHash),
209
+ expectedRevision: this.#revision,
210
+ candidateDocument: structuredClone(event.candidateDocument),
211
+ candidateWorkspace,
212
+ });
213
+ }
214
+ catch (error) {
215
+ this.#rejectCandidate(event, new CrossPeriodDrawingError('CROSS_PERIOD_PERSISTENCE_FAILED', '/drawings', errorMessage(error)));
216
+ this.#restoreReadyAfterPersistence();
217
+ return;
218
+ }
219
+ if (receipt.canonicalHash !== event.canonicalHash) {
220
+ this.#rejectCandidate(event, new CrossPeriodDrawingError('CROSS_PERIOD_PERSISTENCE_HASH_MISMATCH', '/drawings', 'The persistence receipt hash does not match the Runtime candidate hash.'));
221
+ this.#restoreReadyAfterPersistence();
222
+ return;
223
+ }
224
+ try {
225
+ if (!this.#runtime.commitDrawingChange(event.requestId, event.canonicalHash)) {
226
+ throw new Error('Workspace Runtime did not commit the persisted candidate.');
227
+ }
228
+ }
229
+ catch (error) {
230
+ this.#enterTerminalError('CROSS_PERIOD_COMMIT_AFTER_PERSIST_FAILED', `Persistence succeeded but Runtime commit failed: ${errorMessage(error)}`);
231
+ return;
232
+ }
233
+ this.#revision = receipt.revision;
234
+ this.#emit({
235
+ type: 'drawing-persistence-committed',
236
+ requestId: event.requestId,
237
+ canonicalHash: event.canonicalHash,
238
+ revision: this.#revision,
239
+ });
240
+ this.#restoreReadyAfterPersistence();
241
+ }
242
+ #candidateWorkspace(document) {
243
+ if (document.scopeKey !== this.#binding.scopeKey) {
244
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_SCOPE_MISMATCH', '/drawings/scopeKey', 'Drawing candidate scopeKey does not match the instrument binding.');
245
+ }
246
+ const current = this.#runtime.exportWorkspace();
247
+ this.#assertWorkspaceScope(current, this.#binding);
248
+ return parseDrawableWorkspaceDocument({
249
+ ...structuredClone(current),
250
+ drawings: structuredClone(document),
251
+ binding: {
252
+ scopeKey: document.scopeKey,
253
+ timezone: document.coordinateSystem.timezone,
254
+ valueAxes: structuredClone(document.coordinateSystem.valueAxes),
255
+ },
256
+ });
257
+ }
258
+ #rejectCandidate(event, error) {
259
+ try {
260
+ if (!this.#runtime.rejectDrawingChange(event.requestId)) {
261
+ throw new Error('Workspace Runtime could not restore the rejected candidate.');
262
+ }
263
+ }
264
+ catch (rejectionError) {
265
+ this.#enterTerminalError('CROSS_PERIOD_CANDIDATE_RESTORE_FAILED', `Candidate rejection failed: ${errorMessage(rejectionError)}`);
266
+ return;
267
+ }
268
+ this.#emit({
269
+ type: 'drawing-persistence-rejected',
270
+ requestId: event.requestId,
271
+ canonicalHash: event.canonicalHash,
272
+ code: error.code,
273
+ message: error.message,
274
+ });
275
+ }
276
+ #restoreReadyAfterPersistence() {
277
+ if (this.#state === 'persisting-drawing') {
278
+ this.#setState('ready');
279
+ }
280
+ }
281
+ #assertWorkspaceScope(workspace, binding) {
282
+ if (workspace.drawings.scopeKey !== binding.scopeKey ||
283
+ workspace.binding.scopeKey !== binding.scopeKey) {
284
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_SCOPE_MISMATCH', '/scopeKey', 'Workspace scopeKey does not match the explicit instrument binding.');
285
+ }
286
+ }
287
+ #assertReady() {
288
+ this.#assertUsable();
289
+ if (this.#state !== 'ready') {
290
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_OPERATION_IN_PROGRESS', '/', `Cross-period coordinator is ${this.#state}.`);
291
+ }
292
+ }
293
+ #assertUsable() {
294
+ if (this.#state === 'destroyed' || this.#state === 'terminal-error') {
295
+ throw new CrossPeriodDrawingError('CROSS_PERIOD_RUNTIME_DESTROYED', '/', 'The cross-period coordinator is in a destroy-only state.');
296
+ }
297
+ }
298
+ #enterTerminalError(code, message) {
299
+ const error = new CrossPeriodDrawingError(code, '/', message);
300
+ this.#setState('terminal-error');
301
+ this.#emit({ type: 'terminal-error', code, message });
302
+ return error;
303
+ }
304
+ #setState(state) {
305
+ this.#state = state;
306
+ this.#emit({ type: 'state-changed', state });
307
+ }
308
+ #track(operation) {
309
+ this.#pendingOperations.add(operation);
310
+ void operation.finally(() => {
311
+ this.#pendingOperations.delete(operation);
312
+ });
313
+ }
314
+ #emit(event) {
315
+ const snapshot = deepFreeze(structuredClone(event));
316
+ for (const listener of this.#listeners) {
317
+ try {
318
+ listener(structuredClone(snapshot));
319
+ }
320
+ catch {
321
+ // 宿主监听器不能改变编排状态或阻断其他监听器。
322
+ }
323
+ }
324
+ }
325
+ }
326
+ export function createCrossPeriodDrawingCoordinator(runtime, binding, options) {
327
+ return new CrossPeriodDrawingCoordinator(runtime, binding, options);
328
+ }
@@ -17,6 +17,10 @@ export interface MainSeriesPresentationCapability {
17
17
  export interface HostActionDescriptor {
18
18
  readonly actionId: string;
19
19
  readonly label: string;
20
+ readonly pressed?: boolean;
21
+ readonly disabled?: boolean;
22
+ readonly pending?: boolean;
23
+ readonly errorMessage?: string;
20
24
  }
21
25
  export interface RuntimeCapabilityDescriptor {
22
26
  readonly drawingTypes: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"runtime-capability-descriptor.d.ts","sourceRoot":"","sources":["../../src/drawing/runtime-capability-descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC;IAChE,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,aAAa,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC/C,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,oBAAoB,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,gCAAgC;IAChD,QAAQ,CAAC,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC1D,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,0BAA0B,CAAC;IAC/C,QAAQ,CAAC,cAAc,EAAE,+BAA+B,CAAC;IACzD,QAAQ,CAAC,sBAAsB,EAAE,gCAAgC,GAAG,IAAI,CAAC;IACzE,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACtD"}
1
+ {"version":3,"file":"runtime-capability-descriptor.d.ts","sourceRoot":"","sources":["../../src/drawing/runtime-capability-descriptor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,sBAAsB,EACtB,oBAAoB,EACpB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,CAAC,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC;IAChE,QAAQ,CAAC,WAAW,EAAE,QAAQ,GAAG,aAAa,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,+BAA+B;IAC/C,QAAQ,CAAC,IAAI,EAAE,aAAa,GAAG,oBAAoB,CAAC;IACpD,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,gCAAgC;IAChD,QAAQ,CAAC,aAAa,EAAE,SAAS,sBAAsB,EAAE,CAAC;IAC1D,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,0BAA0B,CAAC;IAC/C,QAAQ,CAAC,cAAc,EAAE,+BAA+B,CAAC;IACzD,QAAQ,CAAC,sBAAsB,EAAE,gCAAgC,GAAG,IAAI,CAAC;IACzE,QAAQ,CAAC,WAAW,EAAE,SAAS,oBAAoB,EAAE,CAAC;CACtD"}
@@ -35,6 +35,8 @@ export declare class DrawingSessionController {
35
35
  get state(): DrawingSessionState;
36
36
  get confirmedDrawings(): readonly EngineDrawingSnapshot[];
37
37
  get selectedId(): string | null;
38
+ /** 当前已确认的投影 Scene;仅返回深拷贝,协调层不能取得引擎对象。 */
39
+ get projectionScene(): ProjectionScene;
38
40
  restoreConfirmed(drawings: readonly EngineDrawingSnapshot[]): void;
39
41
  startCreate(type: string, options?: {
40
42
  readonly text?: string;
@@ -45,6 +47,13 @@ export declare class DrawingSessionController {
45
47
  updateDrawingText(id: string, text: string): EngineDrawingSnapshot;
46
48
  removeDrawing(id: string): boolean;
47
49
  selectDrawing(id: string | null): void;
50
+ /**
51
+ * 在同一个 Adapter 内原子替换 Scene 投影上下文。
52
+ * 候选 Scene 先以 confirmed Drawing 全量验证,成功应用引擎后才提升为当前投影 Scene。
53
+ */
54
+ replaceProjectionScene<T>(scene: ProjectionScene, apply: () => T): T;
55
+ /** 异步版本用于轴等需要等待 Adapter 原子应用完成的 Scene 事务。 */
56
+ replaceProjectionSceneAsync<T>(scene: ProjectionScene, apply: () => Promise<T>): Promise<T>;
48
57
  commitDrawingChange(requestId: string, canonicalHash: string): boolean;
49
58
  rejectDrawingChange(requestId: string): boolean;
50
59
  enterTerminalError(code: string, message: string): void;
@@ -1 +1 @@
1
- {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/drawing/session-controller.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/drawing/session-controller.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,8 @@ export class DrawingSessionError extends Error {
17
17
  */
18
18
  export class DrawingSessionController {
19
19
  #options;
20
+ /** 后续 Drawing 候选投影必须使用的当前已确认 Scene。 */
21
+ #scene;
20
22
  #state = 'ready';
21
23
  #confirmed = [];
22
24
  #candidate = null;
@@ -26,6 +28,7 @@ export class DrawingSessionController {
26
28
  #unsubscribeEngine;
27
29
  constructor(options) {
28
30
  this.#options = options;
31
+ this.#scene = structuredClone(options.scene);
29
32
  this.#unsubscribeEngine = options.engine.subscribeDrawingEvents((event) => this.#handleEngineEvent(event));
30
33
  }
31
34
  get state() {
@@ -38,6 +41,11 @@ export class DrawingSessionController {
38
41
  get selectedId() {
39
42
  return this.#selectedId;
40
43
  }
44
+ /** 当前已确认的投影 Scene;仅返回深拷贝,协调层不能取得引擎对象。 */
45
+ get projectionScene() {
46
+ this.#assertUsable();
47
+ return structuredClone(this.#scene);
48
+ }
41
49
  restoreConfirmed(drawings) {
42
50
  this.#assertUsable();
43
51
  this.#suppressEngineEvents = true;
@@ -87,6 +95,69 @@ export class DrawingSessionController {
87
95
  id,
88
96
  });
89
97
  }
98
+ /**
99
+ * 在同一个 Adapter 内原子替换 Scene 投影上下文。
100
+ * 候选 Scene 先以 confirmed Drawing 全量验证,成功应用引擎后才提升为当前投影 Scene。
101
+ */
102
+ replaceProjectionScene(scene, apply) {
103
+ this.#assertReady();
104
+ const candidate = structuredClone(scene);
105
+ this.#options.projectionService.projectDocument({
106
+ scene: candidate,
107
+ drawings: this.#options.buildDocument(this.#confirmed),
108
+ });
109
+ this.#state = 'reprojecting';
110
+ let mutationsDisabled = false;
111
+ try {
112
+ this.#options.engine.setMutationsEnabled(false);
113
+ mutationsDisabled = true;
114
+ const result = apply();
115
+ this.#scene = candidate;
116
+ return result;
117
+ }
118
+ finally {
119
+ if (mutationsDisabled) {
120
+ try {
121
+ this.#options.engine.setMutationsEnabled(true);
122
+ }
123
+ catch (error) {
124
+ this.#enterTerminalError('DRAWING_PROJECTION_INVALID', `Failed to restore Drawing mutations after Scene replacement: ${String(error)}`);
125
+ throw new DrawingSessionError('DRAWING_PROJECTION_INVALID', '/scene', 'The Drawing engine could not leave the Scene replacement state.');
126
+ }
127
+ }
128
+ this.#state = 'ready';
129
+ }
130
+ }
131
+ /** 异步版本用于轴等需要等待 Adapter 原子应用完成的 Scene 事务。 */
132
+ async replaceProjectionSceneAsync(scene, apply) {
133
+ this.#assertReady();
134
+ const candidate = structuredClone(scene);
135
+ this.#options.projectionService.projectDocument({
136
+ scene: candidate,
137
+ drawings: this.#options.buildDocument(this.#confirmed),
138
+ });
139
+ this.#state = 'reprojecting';
140
+ let mutationsDisabled = false;
141
+ try {
142
+ this.#options.engine.setMutationsEnabled(false);
143
+ mutationsDisabled = true;
144
+ const result = await apply();
145
+ this.#scene = candidate;
146
+ return result;
147
+ }
148
+ finally {
149
+ if (mutationsDisabled) {
150
+ try {
151
+ this.#options.engine.setMutationsEnabled(true);
152
+ }
153
+ catch (error) {
154
+ this.#enterTerminalError('DRAWING_PROJECTION_INVALID', `Failed to restore Drawing mutations after Scene replacement: ${String(error)}`);
155
+ throw new DrawingSessionError('DRAWING_PROJECTION_INVALID', '/scene', 'The Drawing engine could not leave the Scene replacement state.');
156
+ }
157
+ }
158
+ this.#state = 'ready';
159
+ }
160
+ }
90
161
  commitDrawingChange(requestId, canonicalHash) {
91
162
  this.#assertUsable();
92
163
  if (this.#state !== 'awaiting-host-confirmation') {
@@ -225,7 +296,7 @@ export class DrawingSessionController {
225
296
  const candidateDocument = this.#options.buildDocument(this.#confirmedWith(input.operation, input.before, input.after));
226
297
  try {
227
298
  const projected = this.#options.projectionService.projectDocument({
228
- scene: this.#options.scene,
299
+ scene: this.#scene,
229
300
  drawings: candidateDocument,
230
301
  });
231
302
  if (input.after !== undefined && input.operation !== 'delete') {
@@ -2,6 +2,7 @@ import type { ChartScene, DrawableWorkspaceDocument, Drawing, DrawingDocument, T
2
2
  import type { EngineDrawingSnapshot, MainSeriesPresentation } from '@baron1996/klinecharts-adapter';
3
3
  import type { DrawingRuntimeCapability, RuntimeAuxiliaryCapability } from './capabilities.js';
4
4
  import type { HostActionDescriptor, RuntimeCapabilityDescriptor } from './runtime-capability-descriptor.js';
5
+ import { DrawingSessionController } from './session-controller.js';
5
6
  import { type WorkspaceRuntimeListener } from './workspace-events.js';
6
7
  export interface DrawableWorkspaceRuntimeOptions {
7
8
  readonly commitMode: 'immediate' | 'host-confirmed';
@@ -18,6 +19,10 @@ export declare class DrawableWorkspaceRuntime implements DrawableWorkspaceRuntim
18
19
  #private;
19
20
  private constructor();
20
21
  static create(container: HTMLElement, value: unknown, options: DrawableWorkspaceRuntimeOptions): Promise<DrawableWorkspaceRuntime>;
22
+ /** 跨周期等宿主编排只能连接显式 host-confirmed Runtime。 */
23
+ get commitMode(): DrawableWorkspaceRuntimeOptions['commitMode'];
24
+ /** 只暴露公共会话状态,不暴露 Adapter 或 Chart。 */
25
+ getDrawingSessionState(): DrawingSessionController['state'];
21
26
  startDrawing(type: Drawing['type'], options?: {
22
27
  readonly text?: string;
23
28
  readonly id?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"workspace-runtime.d.ts","sourceRoot":"","sources":["../../src/drawing/workspace-runtime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workspace-runtime.d.ts","sourceRoot":"","sources":["../../src/drawing/workspace-runtime.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,8 @@ export class DrawableWorkspaceRuntime {
42
42
  #projectionService = new DrawingProjectionService();
43
43
  #registration;
44
44
  #runtimeId;
45
+ /** 宿主确认策略在 Runtime 生命周期内不可切换。 */
46
+ #commitMode;
45
47
  #listeners = new Set();
46
48
  #sequence = 0;
47
49
  #destroyed = false;
@@ -50,6 +52,7 @@ export class DrawableWorkspaceRuntime {
50
52
  this.#container = container;
51
53
  this.#workspace = workspace;
52
54
  this.#engine = engine;
55
+ this.#commitMode = options.commitMode;
53
56
  this.#runtimeId = `drawable-workspace-${Math.random().toString(36).slice(2)}`;
54
57
  this.#scene = workspace.scene.document;
55
58
  this.#registration = getSceneRuntime(workspace.scene.kind);
@@ -77,6 +80,14 @@ export class DrawableWorkspaceRuntime {
77
80
  const engine = await registration.createAdapter(container, workspace);
78
81
  return new DrawableWorkspaceRuntime(container, workspace, engine, options);
79
82
  }
83
+ /** 跨周期等宿主编排只能连接显式 host-confirmed Runtime。 */
84
+ get commitMode() {
85
+ return this.#commitMode;
86
+ }
87
+ /** 只暴露公共会话状态,不暴露 Adapter 或 Chart。 */
88
+ getDrawingSessionState() {
89
+ return this.#session.state;
90
+ }
80
91
  startDrawing(type, options) {
81
92
  return this.#session.startCreate(type, options);
82
93
  }
@@ -209,7 +220,10 @@ export class DrawableWorkspaceRuntime {
209
220
  });
210
221
  this.#assertSceneProjection(candidate);
211
222
  const engine = this.#engine;
212
- await engine.setPriceScale(scale);
223
+ await this.#session.replaceProjectionSceneAsync({
224
+ kind: 'chart',
225
+ document: candidate,
226
+ }, () => engine.setPriceScale(scale));
213
227
  this.#scene = candidate;
214
228
  this.#emit({ type: 'value-axis-scale-changed', scale });
215
229
  return structuredClone(candidate);
@@ -235,9 +249,11 @@ export class DrawableWorkspaceRuntime {
235
249
  (this.#sceneKind() === 'time-series' && !('series' in candidate))) {
236
250
  throw new Error('DRAWABLE_SCENE_KIND_UNSUPPORTED: cross-kind replacement is rejected.');
237
251
  }
238
- this.#assertSceneProjection(candidate);
239
252
  const engine = this.#engine;
240
- const applied = engine.replaceScene(candidate);
253
+ const applied = this.#session.replaceProjectionScene({
254
+ kind: this.#sceneKind(),
255
+ document: candidate,
256
+ }, () => engine.replaceScene(candidate));
241
257
  this.#scene = applied;
242
258
  this.#emit({ type: 'scene-replaced', scene: { kind: this.#sceneKind(), document: applied } });
243
259
  return structuredClone(applied);
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  /** Web Runtime npm 包版本;ChartScene runtimeVersion 是独立的数据契约版本。 */
2
- export declare const WEB_RUNTIME_PACKAGE_VERSION: "0.5.1";
2
+ export declare const WEB_RUNTIME_PACKAGE_VERSION: "0.7.1";
3
3
  export { SUPPORTED_OVERLAYS } from '@baron1996/klinecharts-adapter';
4
+ export * from './cross-period/coordinator.js';
4
5
  export * from './drawing/capabilities.js';
5
6
  export * from './drawing/projection-service.js';
6
7
  export * from './drawing/runtime-capability-descriptor.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,EAAG,OAAgB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iCAAiC,CAAC;AAChD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  /** Web Runtime npm 包版本;ChartScene runtimeVersion 是独立的数据契约版本。 */
2
- export const WEB_RUNTIME_PACKAGE_VERSION = '0.5.1';
2
+ export const WEB_RUNTIME_PACKAGE_VERSION = '0.7.1';
3
3
  export { SUPPORTED_OVERLAYS } from '@baron1996/klinecharts-adapter';
4
+ export * from './cross-period/coordinator.js';
4
5
  export * from './drawing/capabilities.js';
5
6
  export * from './drawing/projection-service.js';
6
7
  export * from './drawing/runtime-capability-descriptor.js';
@@ -1 +1 @@
1
- {"version":3,"file":"standard-toolbar-styles.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,QA8QnC,CAAC"}
1
+ {"version":3,"file":"standard-toolbar-styles.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar-styles.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB,QAkTnC,CAAC"}
@@ -88,6 +88,19 @@ export const STANDARD_TOOLBAR_STYLES = String.raw `
88
88
  font-size: 11px;
89
89
  }
90
90
 
91
+ .baron-kline-toolbar__host-action-error {
92
+ flex: 0 0 auto;
93
+ max-width: 260px;
94
+ padding: 0 6px;
95
+ color: rgba(194, 57, 52, 1);
96
+ font-size: 11px;
97
+ line-height: 1.35;
98
+ }
99
+
100
+ .baron-kline-toolbar__host-action-error[hidden] {
101
+ display: none;
102
+ }
103
+
91
104
  .baron-kline-toolbar__button {
92
105
  position: relative;
93
106
  display: grid;
@@ -113,6 +126,29 @@ export const STANDARD_TOOLBAR_STYLES = String.raw `
113
126
  transform: translateY(-1px);
114
127
  }
115
128
 
129
+ .baron-kline-toolbar__button:disabled {
130
+ cursor: not-allowed;
131
+ opacity: 0.5;
132
+ transform: none;
133
+ }
134
+
135
+ .baron-kline-toolbar__button[aria-busy="true"]::after {
136
+ width: 10px;
137
+ height: 10px;
138
+ margin-left: 5px;
139
+ content: "";
140
+ border: 1.5px solid currentcolor;
141
+ border-right-color: transparent;
142
+ border-radius: 50%;
143
+ animation: baron-kline-toolbar-spin 700ms linear infinite;
144
+ }
145
+
146
+ @keyframes baron-kline-toolbar-spin {
147
+ to {
148
+ transform: rotate(360deg);
149
+ }
150
+ }
151
+
116
152
  .baron-kline-toolbar__button:focus-visible {
117
153
  outline: 2px solid rgba(41, 98, 255, 1);
118
154
  outline-offset: 2px;
@@ -1 +1 @@
1
- {"version":3,"file":"standard-toolbar.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACX,eAAe,EACf,sBAAsB,EAEtB,MAAM,aAAa,CAAC;AAyCrB,KAAK,sBAAsB,GAAG,wBAAwB,GAAG,0BAA0B,CAAC;AA0LpF,2BAA2B;AAC3B,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,GAAE,sBAA2B,GAClC,eAAe,CA2YjB"}
1
+ {"version":3,"file":"standard-toolbar.d.ts","sourceRoot":"","sources":["../../src/toolbar/standard-toolbar.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,wBAAwB,EACxB,0BAA0B,EAC1B,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACX,eAAe,EACf,sBAAsB,EAEtB,MAAM,aAAa,CAAC;AA4ErB,KAAK,sBAAsB,GAAG,wBAAwB,GAAG,0BAA0B,CAAC;AA0LpF,2BAA2B;AAC3B,wBAAgB,qBAAqB,CACpC,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,sBAAsB,EAC/B,OAAO,GAAE,sBAA2B,GAClC,eAAe,CA4ajB"}
@@ -4,6 +4,28 @@ import { createToolbarIcon } from './toolbar-icons.js';
4
4
  import { STANDARD_TOOLBAR_STYLES } from './standard-toolbar-styles.js';
5
5
  import { OVERLAY_TOOL_PRESENTATIONS, TEXT_OVERLAY_TYPES, TOOLBAR_ACTIONS, TOOLBAR_GROUPS, } from './toolbar-tools.js';
6
6
  let nextToolbarId = 1;
7
+ function applyHostActionState(control, state) {
8
+ if (state.pressed !== undefined) {
9
+ control.button.setAttribute('aria-pressed', String(state.pressed));
10
+ }
11
+ if (state.disabled !== undefined) {
12
+ control.button.disabled = state.disabled;
13
+ }
14
+ if (state.pending !== undefined) {
15
+ control.button.setAttribute('aria-busy', String(state.pending));
16
+ }
17
+ if ('errorMessage' in state) {
18
+ const message = state.errorMessage?.trim() ?? '';
19
+ control.error.textContent = message;
20
+ control.error.hidden = message.length === 0;
21
+ if (message.length === 0) {
22
+ control.button.removeAttribute('aria-errormessage');
23
+ }
24
+ else {
25
+ control.button.setAttribute('aria-errormessage', control.error.id);
26
+ }
27
+ }
28
+ }
7
29
  /** 将 HTML color 控件的 #RRGGBB 边界值归一化为 Scene v1 唯一的 rgba 表示。 */
8
30
  function htmlHexColorToSceneRgba(value) {
9
31
  const match = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(value);
@@ -153,6 +175,13 @@ function createInputControl(labelText, action, type) {
153
175
  /** 创建不含撤销/重做的标准离线编辑工具栏。 */
154
176
  export function createStandardToolbar(container, runtime, options = {}) {
155
177
  const descriptor = runtime.getRuntimeCapabilityDescriptor(options.hostActions === undefined ? {} : { hostActions: options.hostActions });
178
+ const hostActionIds = new Set();
179
+ for (const hostAction of descriptor.hostActions) {
180
+ if (hostActionIds.has(hostAction.actionId)) {
181
+ throw new TypeError(`STANDARD_TOOLBAR_DUPLICATE_HOST_ACTION: ${hostAction.actionId}`);
182
+ }
183
+ hostActionIds.add(hostAction.actionId);
184
+ }
156
185
  const defaultFileName = options.downloadFileName
157
186
  ?? descriptor.exportArtifact.defaultFileName;
158
187
  const toolbarId = nextToolbarId++;
@@ -172,6 +201,7 @@ export function createStandardToolbar(container, runtime, options = {}) {
172
201
  const tooltip = createTooltip(viewport, `baron-kline-toolbar-tooltip-${toolbarId}`);
173
202
  const cleanupCallbacks = [];
174
203
  const overlayButtons = [];
204
+ const hostActionControls = new Map();
175
205
  const textInput = document.createElement('input');
176
206
  textInput.type = 'text';
177
207
  textInput.className = 'baron-kline-toolbar__text-input';
@@ -408,9 +438,22 @@ export function createStandardToolbar(container, runtime, options = {}) {
408
438
  button.dataset.hostAction = hostAction.actionId;
409
439
  button.textContent = hostAction.label;
410
440
  button.setAttribute('aria-label', hostAction.label);
441
+ button.setAttribute('aria-pressed', String(hostAction.pressed ?? false));
442
+ button.setAttribute('aria-busy', String(hostAction.pending ?? false));
443
+ button.disabled = hostAction.disabled ?? false;
444
+ const error = document.createElement('span');
445
+ error.id = `baron-kline-toolbar-host-action-error-${toolbarId}-${hostActionControls.size}`;
446
+ error.className = 'baron-kline-toolbar__host-action-error';
447
+ error.setAttribute('role', 'alert');
448
+ error.setAttribute('aria-live', 'assertive');
449
+ const control = { button, error };
450
+ hostActionControls.set(hostAction.actionId, control);
451
+ applyHostActionState(control, {
452
+ errorMessage: hostAction.errorMessage ?? null,
453
+ });
411
454
  const action = () => runtime.requestHostAction(hostAction.actionId, runtime.getSelectedDrawingId() ?? null);
412
455
  button.addEventListener('click', action);
413
- groupElement.append(button);
456
+ groupElement.append(button, error);
414
457
  cleanupCallbacks.push(() => button.removeEventListener('click', action));
415
458
  }
416
459
  }
@@ -451,6 +494,16 @@ export function createStandardToolbar(container, runtime, options = {}) {
451
494
  let unregisterRuntime = () => { };
452
495
  const toolbar = {
453
496
  element: root,
497
+ setHostActionState(actionId, state) {
498
+ if (destroyed) {
499
+ throw new Error('STANDARD_TOOLBAR_DESTROYED');
500
+ }
501
+ const control = hostActionControls.get(actionId);
502
+ if (control === undefined) {
503
+ throw new TypeError(`STANDARD_TOOLBAR_UNKNOWN_HOST_ACTION: ${actionId}`);
504
+ }
505
+ applyHostActionState(control, state);
506
+ },
454
507
  destroy() {
455
508
  if (destroyed) {
456
509
  return;
package/dist/types.d.ts CHANGED
@@ -121,6 +121,12 @@ export interface StandardToolbarOptions {
121
121
  }
122
122
  export interface StandardToolbar {
123
123
  readonly element: HTMLElement;
124
+ setHostActionState(actionId: string, state: {
125
+ readonly pressed?: boolean;
126
+ readonly disabled?: boolean;
127
+ readonly pending?: boolean;
128
+ readonly errorMessage?: string | null;
129
+ }): void;
124
130
  destroy(): void;
125
131
  }
126
132
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,UAAU,EACV,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4CAA4C,CAAC;AAEvF,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,MAAM,WAAW,8BAA8B;IAC9C,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC;IACzB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,uBAAuB,GAChC,QAAQ,GACR,gBAAgB,GAChB,aAAa,GACb,SAAS,GACT,kBAAkB,CAAC;AACtB,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,aAAa,CAAC;AAElD,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;CAC3C;AAED,UAAU,wBAAwB;IACjC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;CAC9B;AAED,KAAK,6BAA6B,GAC/B;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC5D;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACpE;IAAE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACzG;IAAE,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACzD;IAAE,QAAQ,CAAC,IAAI,EAAE,2BAA2B,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC9G;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1D,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,GAAG,wBAAwB,CAAC,GACtE,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GAAG,wBAAwB,CAAC,GACpG,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAAG,wBAAwB,CAAC,GACxG,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,wBAAwB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAA;CAAE,GAAG,wBAAwB,CAAC,GAClH;IAAE,QAAQ,CAAC,IAAI,EAAE,0BAA0B,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,QAAQ,CAAC,IAAI,EAAE,uBAAuB,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACxG;IAAE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAAE,GACnH;IAAE,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAA;CAAE,GACjE;IAAE,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAAC;AAE5E,MAAM,MAAM,sBAAsB,GACjC,6BAA6B,GAAG,8BAA8B,CAAC;AAEhE,MAAM,MAAM,yBAAyB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;AAEhF,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,yBAAyB,CAAC;CAC7C;AAED,MAAM,WAAW,0BAA0B;IAC1C,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvD,QAAQ,CAAC,6BAA6B,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC9D,uDAAuD;IACvD,QAAQ,CAAC,qBAAqB,CAAC,EAAE,SAAS,GAAG,cAAc,CAAC;IAC5D,wDAAwD;IACxD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,WAAW,CAAC;CACzC;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,kBAAkB,CACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE;QACN,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACtC,GACC,IAAI,CAAC;IACR,OAAO,IAAI,IAAI,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@baron1996/klinecharts-runtime",
3
- "version": "0.5.1",
3
+ "version": "0.7.1",
4
4
  "description": "Web runtime for deterministic KLineCharts scenes.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -39,8 +39,8 @@
39
39
  "typecheck": "tsc -p tsconfig.json --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@baron1996/kline-scene-schema": "0.5.1",
43
- "@baron1996/klinecharts-adapter": "0.5.1",
42
+ "@baron1996/kline-scene-schema": "0.6.0",
43
+ "@baron1996/klinecharts-adapter": "0.6.0",
44
44
  "@js-temporal/polyfill": "0.5.1"
45
45
  }
46
46
  }