@lokvis/runtime 0.2.2 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/asset-store.d.ts +13 -0
- package/dist/asset-store.d.ts.map +1 -1
- package/dist/asset-store.js +15 -2
- package/dist/asset-store.js.map +1 -1
- package/dist/batch-processor.d.ts +32 -161
- package/dist/batch-processor.d.ts.map +1 -1
- package/dist/batch-processor.js +107 -333
- package/dist/batch-processor.js.map +1 -1
- package/dist/batch-progress.d.ts +94 -0
- package/dist/batch-progress.d.ts.map +1 -0
- package/dist/batch-progress.js +128 -0
- package/dist/batch-progress.js.map +1 -0
- package/dist/batch-scheduler.d.ts +70 -0
- package/dist/batch-scheduler.d.ts.map +1 -0
- package/dist/batch-scheduler.js +147 -0
- package/dist/batch-scheduler.js.map +1 -0
- package/dist/browser-detect.d.ts +115 -0
- package/dist/browser-detect.d.ts.map +1 -0
- package/dist/browser-detect.js +160 -0
- package/dist/browser-detect.js.map +1 -0
- package/dist/concurrency-controller.d.ts +31 -0
- package/dist/concurrency-controller.d.ts.map +1 -0
- package/dist/concurrency-controller.js +33 -0
- package/dist/concurrency-controller.js.map +1 -0
- package/dist/errors.d.ts +51 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +74 -0
- package/dist/errors.js.map +1 -0
- package/dist/executor.d.ts +9 -0
- package/dist/executor.d.ts.map +1 -1
- package/dist/executor.js +102 -48
- package/dist/executor.js.map +1 -1
- package/dist/history.d.ts.map +1 -1
- package/dist/history.js +3 -2
- package/dist/history.js.map +1 -1
- package/dist/idb-asset-store.d.ts.map +1 -1
- package/dist/idb-asset-store.js +6 -1
- package/dist/idb-asset-store.js.map +1 -1
- package/dist/index.d.ts +17 -15
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -15
- package/dist/index.js.map +1 -1
- package/dist/managers/asset-manager.d.ts +114 -0
- package/dist/managers/asset-manager.d.ts.map +1 -0
- package/dist/managers/asset-manager.js +238 -0
- package/dist/managers/asset-manager.js.map +1 -0
- package/dist/managers/history-manager.d.ts +100 -0
- package/dist/managers/history-manager.d.ts.map +1 -0
- package/dist/managers/history-manager.js +296 -0
- package/dist/managers/history-manager.js.map +1 -0
- package/dist/managers/mcp-manifest-builder.d.ts +18 -0
- package/dist/managers/mcp-manifest-builder.d.ts.map +1 -0
- package/dist/managers/mcp-manifest-builder.js +99 -0
- package/dist/managers/mcp-manifest-builder.js.map +1 -0
- package/dist/managers/quota-manager.d.ts +42 -0
- package/dist/managers/quota-manager.d.ts.map +1 -0
- package/dist/managers/quota-manager.js +126 -0
- package/dist/managers/quota-manager.js.map +1 -0
- package/dist/managers/workflow-coordinator.d.ts +62 -0
- package/dist/managers/workflow-coordinator.d.ts.map +1 -0
- package/dist/managers/workflow-coordinator.js +125 -0
- package/dist/managers/workflow-coordinator.js.map +1 -0
- package/dist/opfs-asset-store.d.ts.map +1 -1
- package/dist/opfs-asset-store.js +12 -2
- package/dist/opfs-asset-store.js.map +1 -1
- package/dist/plugin-context.d.ts +35 -0
- package/dist/plugin-context.d.ts.map +1 -0
- package/dist/plugin-context.js +62 -0
- package/dist/plugin-context.js.map +1 -0
- package/dist/plugin-permissions.d.ts +99 -0
- package/dist/plugin-permissions.d.ts.map +1 -0
- package/dist/plugin-permissions.js +205 -0
- package/dist/plugin-permissions.js.map +1 -0
- package/dist/runtime-impl.d.ts +116 -0
- package/dist/runtime-impl.d.ts.map +1 -0
- package/dist/runtime-impl.js +270 -0
- package/dist/runtime-impl.js.map +1 -0
- package/dist/runtime.d.ts +10 -233
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +12 -978
- package/dist/runtime.js.map +1 -1
- package/dist/test-utils/fakes.d.ts +35 -0
- package/dist/test-utils/fakes.d.ts.map +1 -0
- package/dist/test-utils/fakes.js +60 -0
- package/dist/test-utils/fakes.js.map +1 -0
- package/dist/types.d.ts +113 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/worker-host.d.ts.map +1 -1
- package/dist/worker-host.js +32 -9
- package/dist/worker-host.js.map +1 -1
- package/dist/worker-protocol.d.ts +30 -0
- package/dist/worker-protocol.d.ts.map +1 -1
- package/dist/worker-protocol.js +24 -0
- package/dist/worker-protocol.js.map +1 -1
- package/package.json +2 -2
- package/src/asset-store.ts +32 -2
- package/src/batch-processor.ts +133 -510
- package/src/batch-progress.ts +228 -0
- package/src/batch-scheduler.ts +209 -0
- package/src/browser-detect.ts +221 -0
- package/src/concurrency-controller.ts +52 -0
- package/src/errors.ts +82 -0
- package/src/executor.ts +122 -55
- package/src/history.ts +3 -2
- package/src/idb-asset-store.ts +7 -1
- package/src/index.ts +50 -15
- package/src/managers/asset-manager.ts +259 -0
- package/src/managers/history-manager.ts +327 -0
- package/src/managers/mcp-manifest-builder.ts +108 -0
- package/src/managers/quota-manager.ts +149 -0
- package/src/managers/workflow-coordinator.ts +158 -0
- package/src/opfs-asset-store.ts +16 -2
- package/src/plugin-context.ts +87 -0
- package/src/plugin-permissions.ts +228 -0
- package/src/runtime-impl.ts +298 -0
- package/src/runtime.ts +16 -1116
- package/src/test-utils/fakes.ts +72 -0
- package/src/types.ts +116 -0
- package/src/worker-host.ts +35 -7
- package/src/worker-protocol.ts +47 -0
- package/dist/workflow-builder.d.ts +0 -124
- package/dist/workflow-builder.d.ts.map +0 -1
- package/dist/workflow-builder.js +0 -240
- package/dist/workflow-builder.js.map +0 -1
- package/src/workflow-builder.ts +0 -303
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin 权限沙箱(W18.6)
|
|
3
|
+
*
|
|
4
|
+
* 据插件 PluginConfig.permissions 声明提供:
|
|
5
|
+
* 1. 查询:`has(perm)` / `assertNetworkAllowed(reason)`
|
|
6
|
+
* 2. 主动守卫:`applyNetworkGuard()` 在 try/finally 中临时 monkey-patch
|
|
7
|
+
* fetch / XMLHttpRequest / WebSocket / EventSource,声明 network:none
|
|
8
|
+
* 时这些 API 调用立即抛 NetworkGuardError,restore 函数恢复原实现
|
|
9
|
+
*
|
|
10
|
+
* 设计取舍:
|
|
11
|
+
* - 真正的进程隔离(Realm / Worker / iframe sandbox)不在 W18.6 范围,
|
|
12
|
+
* 这里做 install-time monkey-patch,覆盖 99% 的网络
|
|
13
|
+
* 调用路径(原生 fetch / XHR / WebSocket / EventSource)
|
|
14
|
+
* - 沙箱**仅在 installPlugin() 期间生效**(applyNetworkGuard 在
|
|
15
|
+
* installPlugin 的 try/finally 中应用)。capability execute()
|
|
16
|
+
* 期间**不**应用 network guard —— execute 路径由 plugin 代码
|
|
17
|
+
* 自行据 ctx.sandbox.assertNetworkAllowed() 主动自检
|
|
18
|
+
* - 窗口外(如插件 setTimeout 异步调用)无法覆盖 —— 这是有意为之的
|
|
19
|
+
* "best-effort 守卫",plugin 作者应据 ctx.sandbox 自检再调用
|
|
20
|
+
* - 文件系统权限(filesystem:opfs / filesystem:local)目前仅做断言,
|
|
21
|
+
* 不 monkey-patch OPFS API(navigator.storage.getDirectory 等覆盖面
|
|
22
|
+
* 有限,留待后续 W18.x 加 strict mode 时补)
|
|
23
|
+
*
|
|
24
|
+
* @see docs/PROJECT_PLAN.md W18.6
|
|
25
|
+
*/
|
|
26
|
+
/** 权限断言失败时抛出(声明 X 但未声明 Y 又调用 Y 时) */
|
|
27
|
+
export class PluginPermissionError extends Error {
|
|
28
|
+
pluginName;
|
|
29
|
+
permission;
|
|
30
|
+
reason;
|
|
31
|
+
constructor(pluginName, permission, reason) {
|
|
32
|
+
super(`Plugin "${pluginName}" permission denied: requires "${permission}" but not declared. ` +
|
|
33
|
+
`Reason: ${reason}`);
|
|
34
|
+
this.name = 'PluginPermissionError';
|
|
35
|
+
this.pluginName = pluginName;
|
|
36
|
+
this.permission = permission;
|
|
37
|
+
this.reason = reason;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/** 网络守卫拦截时抛出(声明 network:none 又调网络 API 时) */
|
|
41
|
+
export class NetworkGuardError extends Error {
|
|
42
|
+
pluginName;
|
|
43
|
+
api;
|
|
44
|
+
constructor(pluginName, api) {
|
|
45
|
+
super(`Plugin "${pluginName}" declared "network:none" but called ${api}(). ` +
|
|
46
|
+
'If network access is required, add "network:limited" or "network:full" to plugin.config.permissions.');
|
|
47
|
+
this.name = 'NetworkGuardError';
|
|
48
|
+
this.pluginName = pluginName;
|
|
49
|
+
this.api = api;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 文件系统守卫拦截时抛出(预留未启用)。
|
|
54
|
+
*
|
|
55
|
+
* W18.6 的 filesystem 权限目前仅做 `assertFilesystemAllowed()` 主动断言
|
|
56
|
+
* (抛 `PluginPermissionError`),不 monkey-patch OPFS API。
|
|
57
|
+
* 此类预留给后续 W18.x strict mode(覆盖 navigator.storage / showOpenFilePicker
|
|
58
|
+
* 等 API)使用,当前为未启用的占位类,生产代码不会抛出此错误。
|
|
59
|
+
*/
|
|
60
|
+
export class FilesystemGuardError extends Error {
|
|
61
|
+
pluginName;
|
|
62
|
+
scope;
|
|
63
|
+
constructor(pluginName, scope) {
|
|
64
|
+
const perm = scope === 'opfs' ? 'filesystem:opfs' : 'filesystem:local';
|
|
65
|
+
super(`Plugin "${pluginName}" called ${scope} filesystem API but did not declare "${perm}". ` +
|
|
66
|
+
'Add it to plugin.config.permissions if filesystem access is intended.');
|
|
67
|
+
this.name = 'FilesystemGuardError';
|
|
68
|
+
this.pluginName = pluginName;
|
|
69
|
+
this.scope = scope;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Plugin 权限沙箱。
|
|
74
|
+
*
|
|
75
|
+
* 一个插件对应一个 sandbox 实例,生命周期与 installPlugin() 一致。
|
|
76
|
+
* applyNetworkGuard() 在 installPlugin 的 try/finally 中应用;
|
|
77
|
+
* capability execute() 路径不自动应用守卫(由 plugin 主动自检)。
|
|
78
|
+
*/
|
|
79
|
+
export class PluginPermissionSandbox {
|
|
80
|
+
pluginName;
|
|
81
|
+
declared;
|
|
82
|
+
constructor(pluginName, permissions) {
|
|
83
|
+
this.pluginName = pluginName;
|
|
84
|
+
this.declared = new Set(permissions ?? []);
|
|
85
|
+
}
|
|
86
|
+
/** 是否声明了指定权限 */
|
|
87
|
+
has(perm) {
|
|
88
|
+
return this.declared.has(perm);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* 断言网络调用允许(声明 network:none 时抛错)。
|
|
92
|
+
*
|
|
93
|
+
* Plugin 在调用 fetch / XHR 等前可主动调用:
|
|
94
|
+
* ctx.sandbox.assertNetworkAllowed('loading model manifest')
|
|
95
|
+
* 若声明了 network:none,立即抛 PluginPermissionError;否则 no-op。
|
|
96
|
+
*/
|
|
97
|
+
assertNetworkAllowed(reason) {
|
|
98
|
+
if (this.declared.has('network:none')) {
|
|
99
|
+
throw new PluginPermissionError(this.pluginName, 'network:none', reason);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 断言文件系统访问允许(声明未含对应 filesystem:* 时抛错)。
|
|
104
|
+
*
|
|
105
|
+
* @param scope 'opfs'(OPFS 根目录访问)或 'local'(任意本地文件系统)
|
|
106
|
+
*/
|
|
107
|
+
assertFilesystemAllowed(scope, reason) {
|
|
108
|
+
const required = scope === 'opfs' ? 'filesystem:opfs' : 'filesystem:local';
|
|
109
|
+
if (!this.declared.has(required)) {
|
|
110
|
+
throw new PluginPermissionError(this.pluginName, required, reason);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* 应用网络守卫(network:none 声明时,monkey-patch fetch/XHR/WebSocket/
|
|
115
|
+
* EventSource 使其调用即抛 NetworkGuardError)。
|
|
116
|
+
*
|
|
117
|
+
* 返回 restore 函数,必须在 try/finally 中调用以恢复全局 API。
|
|
118
|
+
* 非限制插件(network:limited / network:full / 未声明)返回 no-op。
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* const restore = sandbox.applyNetworkGuard();
|
|
123
|
+
* try {
|
|
124
|
+
* await plugin.install(ctx);
|
|
125
|
+
* } finally {
|
|
126
|
+
* restore();
|
|
127
|
+
* }
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
130
|
+
applyNetworkGuard() {
|
|
131
|
+
if (!this.declared.has('network:none')) {
|
|
132
|
+
return () => {
|
|
133
|
+
/* no-op: plugin未声明 network:none */
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
const pluginName = this.pluginName;
|
|
137
|
+
const blocked = (api) => {
|
|
138
|
+
throw new NetworkGuardError(pluginName, api);
|
|
139
|
+
};
|
|
140
|
+
// 保存原实现(部分 API 在非浏览器环境可能不存在,条件守卫)
|
|
141
|
+
// 注:TS DOM lib 将 fetch/XHR/WebSocket/EventSource 声明为总是定义,
|
|
142
|
+
// 但 Node.js 等非浏览器环境实际为 undefined。用 `as ... | undefined`
|
|
143
|
+
// 让 `if (x)` 守卫不被 TS 视为恒真(TS2774)。
|
|
144
|
+
const origFetch = globalThis.fetch;
|
|
145
|
+
const OrigXHR = globalThis.XMLHttpRequest;
|
|
146
|
+
const origXHRopen = OrigXHR?.prototype.open;
|
|
147
|
+
const origWebSocket = globalThis.WebSocket;
|
|
148
|
+
const origEventSource = globalThis.EventSource;
|
|
149
|
+
// patch fetch(全局函数) — blocked 返回 never,故 () => blocked(...) 类型为
|
|
150
|
+
// () => never,可赋值给任意函数类型(包括 typeof fetch 的重载签名)
|
|
151
|
+
if (origFetch) {
|
|
152
|
+
globalThis.fetch = (() => blocked('fetch'));
|
|
153
|
+
}
|
|
154
|
+
// patch XMLHttpRequest.open(原型方法,跨边界 monkey-patch)
|
|
155
|
+
// 用 Object.defineProperty 替代直接赋值:PropertyDescriptor.value 为 any,
|
|
156
|
+
// 无需为 `() => never` 与原生重载签名的不兼容做 `as unknown as` 双断言
|
|
157
|
+
// (TD-4.5)。writable/configurable 显式为 true,与原生原型方法描述符一致。
|
|
158
|
+
if (OrigXHR) {
|
|
159
|
+
Object.defineProperty(OrigXHR.prototype, 'open', {
|
|
160
|
+
value: function (..._args) {
|
|
161
|
+
return blocked('XMLHttpRequest.open');
|
|
162
|
+
},
|
|
163
|
+
writable: true,
|
|
164
|
+
configurable: true,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// patch WebSocket(构造器,需支持 new;跨边界 monkey-patch)
|
|
168
|
+
if (origWebSocket) {
|
|
169
|
+
const BlockedWS = function (..._args) {
|
|
170
|
+
return blocked('WebSocket');
|
|
171
|
+
};
|
|
172
|
+
// 保留原型链,instanceof 检查仍可通过(虽然实际不会构造成功)
|
|
173
|
+
BlockedWS.prototype = origWebSocket.prototype;
|
|
174
|
+
Object.defineProperty(globalThis, 'WebSocket', {
|
|
175
|
+
value: BlockedWS,
|
|
176
|
+
writable: true,
|
|
177
|
+
configurable: true,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
// patch EventSource(构造器,跨边界 monkey-patch)
|
|
181
|
+
if (origEventSource) {
|
|
182
|
+
const BlockedES = function (..._args) {
|
|
183
|
+
return blocked('EventSource');
|
|
184
|
+
};
|
|
185
|
+
BlockedES.prototype = origEventSource.prototype;
|
|
186
|
+
Object.defineProperty(globalThis, 'EventSource', {
|
|
187
|
+
value: BlockedES,
|
|
188
|
+
writable: true,
|
|
189
|
+
configurable: true,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
// restore 函数
|
|
193
|
+
return () => {
|
|
194
|
+
if (origFetch)
|
|
195
|
+
globalThis.fetch = origFetch;
|
|
196
|
+
if (OrigXHR && origXHRopen)
|
|
197
|
+
OrigXHR.prototype.open = origXHRopen;
|
|
198
|
+
if (origWebSocket)
|
|
199
|
+
globalThis.WebSocket = origWebSocket;
|
|
200
|
+
if (origEventSource)
|
|
201
|
+
globalThis.EventSource = origEventSource;
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=plugin-permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-permissions.js","sourceRoot":"","sources":["../src/plugin-permissions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lokvis Runtime Implementation(W1.7 从 runtime.ts 拆出)
|
|
3
|
+
*
|
|
4
|
+
* 实现 LokvisRuntime 接口,持有 5 个 managers + plugin-context,所有方法转发到
|
|
5
|
+
* 对应 manager。runtime.ts 仅 re-export 本模块,保持外部导入路径不变。
|
|
6
|
+
*/
|
|
7
|
+
import type { Asset, AssetId, AssetSource, Capability, ExifData, HistoryEntry, ImageMetadata, McpManifest, MetadataReader, PdfInfo } from '@lokvis/schema';
|
|
8
|
+
import type { Workflow, WorkflowResult } from '@lokvis/schema';
|
|
9
|
+
import type { EventBus } from '@lokvis/schema';
|
|
10
|
+
import type { InternalRuntimeInit, LokvisRuntime, Plan, PluginInstallEntry, RunOptions, RuntimeConfig, RuntimeStatus, ToMcpManifestOptions } from './types.js';
|
|
11
|
+
import { type AssetStore } from './asset-store.js';
|
|
12
|
+
import { CapabilityRegistry } from './capability-registry.js';
|
|
13
|
+
import { BatchProcessor } from './batch-processor.js';
|
|
14
|
+
import { MemoryGuard } from './memory-guard.js';
|
|
15
|
+
export declare const RUNTIME_VERSION = "0.1.0";
|
|
16
|
+
/** Runtime 实现类,持有 5 个 managers 并委托方法 */
|
|
17
|
+
export declare class LokvisRuntimeImpl implements LokvisRuntime {
|
|
18
|
+
readonly version = "0.1.0";
|
|
19
|
+
readonly eventBus: EventBus;
|
|
20
|
+
private config;
|
|
21
|
+
private assetStore;
|
|
22
|
+
private assetManager;
|
|
23
|
+
private capabilityRegistry;
|
|
24
|
+
private executor;
|
|
25
|
+
private memoryGuard;
|
|
26
|
+
private batchProcessor;
|
|
27
|
+
private historyManager;
|
|
28
|
+
private workflowCoordinator;
|
|
29
|
+
private historyStore;
|
|
30
|
+
private metadataReaders;
|
|
31
|
+
private disposed;
|
|
32
|
+
private readonly ownsAssetStore;
|
|
33
|
+
/** 注册元数据读取器(由 PluginContext.registerMetadataReader 转发,内部 API) */
|
|
34
|
+
_registerMetadataReader(name: string, reader: MetadataReader): void;
|
|
35
|
+
constructor(config?: RuntimeConfig & InternalRuntimeInit);
|
|
36
|
+
get status(): RuntimeStatus;
|
|
37
|
+
get isPro(): boolean;
|
|
38
|
+
get plan(): Plan;
|
|
39
|
+
get batch(): BatchProcessor;
|
|
40
|
+
run(workflow: Workflow, inputs: AssetId[] | Asset[], options?: RunOptions): Promise<WorkflowResult>;
|
|
41
|
+
cancel(workflowId: string): Promise<void>;
|
|
42
|
+
pause(workflowId: string): Promise<void>;
|
|
43
|
+
resume(workflowId: string): Promise<void>;
|
|
44
|
+
disposeWorkflow(workflowId: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* 销毁整个 Runtime(W21.6)。
|
|
47
|
+
*
|
|
48
|
+
* 顺序:
|
|
49
|
+
* 1. 标记 disposed(阻止后续 run/cancel,防止清理期间新请求进入)
|
|
50
|
+
* 2. executor.cancelAll() —— 取消所有运行中 workflow 的 AbortController
|
|
51
|
+
* 3. batchProcessor.dispose() —— 标记所有非终态 job 为 cancelled + 清理订阅
|
|
52
|
+
* 4. historyManager.disposeAll() —— 清空所有历史栈(reset 触发 onEvict
|
|
53
|
+
* → assetStore.remove 回收 outputs 资产);TD-2.1 改为 await 等待
|
|
54
|
+
* persistHistory 删除 IDB 记录落地
|
|
55
|
+
* 5. 清理 metadataReaders
|
|
56
|
+
* 6. 若 ownsAssetStore(工厂创建而非注入):调用 assetStore.dispose?.()
|
|
57
|
+
* 关闭 Dexie 连接 / 清空内存 Map。注入路径由消费方自行管理。
|
|
58
|
+
*
|
|
59
|
+
* 不清理:
|
|
60
|
+
* - historyStore(由消费方注入或工厂创建,Dexie 连接由浏览器 GC 处理)
|
|
61
|
+
* - eventBus listeners(允许外部已订阅的 listener 仍收到最后一批
|
|
62
|
+
* workflow:cancelled 等事件;若需要清空可单独调 eventBus.clear)
|
|
63
|
+
*
|
|
64
|
+
* 幂等:重复调用为 no-op。
|
|
65
|
+
*/
|
|
66
|
+
dispose(): Promise<void>;
|
|
67
|
+
history(workflowId: string): Promise<HistoryEntry[]>;
|
|
68
|
+
getHistoryState(workflowId: string): Promise<{
|
|
69
|
+
entries: HistoryEntry[];
|
|
70
|
+
cursor: number;
|
|
71
|
+
}>;
|
|
72
|
+
undo(workflowId: string): Promise<void>;
|
|
73
|
+
redo(workflowId: string): Promise<void>;
|
|
74
|
+
jumpTo(workflowId: string, index: number): Promise<void>;
|
|
75
|
+
importAsset(source: AssetSource): Promise<AssetId>;
|
|
76
|
+
getAsset(id: AssetId): Promise<Asset>;
|
|
77
|
+
exportAsset(id: AssetId, format?: string): Promise<Blob>;
|
|
78
|
+
readAssetExif(id: AssetId): Promise<ExifData | null>;
|
|
79
|
+
readAssetImageMetadata(id: AssetId): Promise<ImageMetadata | null>;
|
|
80
|
+
readAssetPdfInfo(id: AssetId): Promise<PdfInfo | null>;
|
|
81
|
+
removeAsset(id: AssetId): Promise<void>;
|
|
82
|
+
listAssets(): Promise<Asset[]>;
|
|
83
|
+
getStorageUsage(): Promise<{
|
|
84
|
+
usage: number;
|
|
85
|
+
quota: number;
|
|
86
|
+
}>;
|
|
87
|
+
capabilities(): Promise<Capability[]>;
|
|
88
|
+
hasCapability(name: string): Promise<boolean>;
|
|
89
|
+
isStubOnly(name: string): Promise<boolean>;
|
|
90
|
+
toMcpManifest(options?: ToMcpManifestOptions): McpManifest;
|
|
91
|
+
/**
|
|
92
|
+
* 安装插件:① 注册能力声明 → ② 构造权限沙箱 → ③ 构造受限 PluginContext
|
|
93
|
+
* → ④ 应用 network guard(声明 network:none 时 monkey-patch 全局
|
|
94
|
+
* fetch/XHR/WebSocket/EventSource)→ ⑤ 调用 plugin.install(ctx)
|
|
95
|
+
* → ⑥ restore 全局 API → ⑦ 发射 plugin:loaded 事件。不吞错。
|
|
96
|
+
*
|
|
97
|
+
* network guard 仅在 plugin.install() 期间生效;install 后插件若异步调用
|
|
98
|
+
* 网络 API(如 setTimeout 回调)无法覆盖 —— plugin 作者应据 ctx.sandbox
|
|
99
|
+
* 主动断言(best-effort 守卫,见 docs/PROJECT_PLAN.md W18.6)。
|
|
100
|
+
*/
|
|
101
|
+
installPlugin(plugin: PluginInstallEntry): Promise<void>;
|
|
102
|
+
_getAssetStore(): AssetStore;
|
|
103
|
+
_getCapabilityRegistry(): CapabilityRegistry;
|
|
104
|
+
_getMemoryGuard(): MemoryGuard;
|
|
105
|
+
_getCurrentOutputs(workflowId: string): AssetId[];
|
|
106
|
+
getCurrentOutputs(workflowId: string): Promise<AssetId[]>;
|
|
107
|
+
/** 从 historyStore 预加载持久化历史快照(由 createRuntime 工厂在构造后调用一次,impl 初始化钩子)。 */
|
|
108
|
+
loadPersistedHistory(): Promise<void>;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* 创建 Runtime 实例(W2.8 + W2.9)。默认通过 createAssetStore 工厂按 OPFS →
|
|
112
|
+
* IndexedDB → Memory 降级创建 AssetStore 并用配额校验包裹;也可通过
|
|
113
|
+
* config.assetStore 注入自定义 store。async(工厂需异步探测环境)。
|
|
114
|
+
*/
|
|
115
|
+
export declare function createRuntime(config?: RuntimeConfig): Promise<LokvisRuntime>;
|
|
116
|
+
//# sourceMappingURL=runtime-impl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-impl.d.ts","sourceRoot":"","sources":["../src/runtime-impl.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lokvis Runtime Implementation(W1.7 从 runtime.ts 拆出)
|
|
3
|
+
*
|
|
4
|
+
* 实现 LokvisRuntime 接口,持有 5 个 managers + plugin-context,所有方法转发到
|
|
5
|
+
* 对应 manager。runtime.ts 仅 re-export 本模块,保持外部导入路径不变。
|
|
6
|
+
*/
|
|
7
|
+
import { createEventBus } from './event-bus.js';
|
|
8
|
+
import { createAssetStore, createMemoryAssetStore, } from './asset-store.js';
|
|
9
|
+
import { CapabilityRegistry } from './capability-registry.js';
|
|
10
|
+
import { WorkflowExecutor } from './executor.js';
|
|
11
|
+
import { createHistoryStore } from './history-store.js';
|
|
12
|
+
import { BatchProcessor } from './batch-processor.js';
|
|
13
|
+
import { MemoryGuard, DEFAULT_MEMORY_BUDGET } from './memory-guard.js';
|
|
14
|
+
import { wrapAssetStoreWithQuota, } from './managers/quota-manager.js';
|
|
15
|
+
import { AssetManager } from './managers/asset-manager.js';
|
|
16
|
+
import { HistoryManager } from './managers/history-manager.js';
|
|
17
|
+
import { WorkflowCoordinator } from './managers/workflow-coordinator.js';
|
|
18
|
+
import { toMcpManifest as buildMcpManifest } from './managers/mcp-manifest-builder.js';
|
|
19
|
+
import { createPluginContext } from './plugin-context.js';
|
|
20
|
+
import { PluginPermissionSandbox } from './plugin-permissions.js';
|
|
21
|
+
export const RUNTIME_VERSION = '0.1.0';
|
|
22
|
+
/** Runtime 实现类,持有 5 个 managers 并委托方法 */
|
|
23
|
+
export class LokvisRuntimeImpl {
|
|
24
|
+
version = RUNTIME_VERSION;
|
|
25
|
+
eventBus;
|
|
26
|
+
config;
|
|
27
|
+
assetStore; // wrapAssetStoreWithQuota 无条件包裹(含注入路径)
|
|
28
|
+
assetManager;
|
|
29
|
+
capabilityRegistry;
|
|
30
|
+
executor;
|
|
31
|
+
memoryGuard;
|
|
32
|
+
batchProcessor;
|
|
33
|
+
historyManager; // W1.3:历史栈/initialInputs/currentOutputs/持久化守卫
|
|
34
|
+
workflowCoordinator; // W1.4:status 状态机 + run/cancel/pause/resume/disposeWorkflow
|
|
35
|
+
historyStore; // W7.2 历史持久化;undefined 时退化为仅内存历史
|
|
36
|
+
metadataReaders = new Map(); // W7.3/7.4 MetadataReader 依赖反转
|
|
37
|
+
// W21.6: dispose 守卫,防止重复 dispose + 阻止后续 run/cancel 调用
|
|
38
|
+
disposed = false;
|
|
39
|
+
// W21.6: 标记 assetStore 是否由 Runtime 拥有(工厂创建而非注入)。
|
|
40
|
+
// 仅在 ownsAssetStore=true 时 dispose() 才会调用 assetStore.dispose?.()。
|
|
41
|
+
ownsAssetStore;
|
|
42
|
+
/** 注册元数据读取器(由 PluginContext.registerMetadataReader 转发,内部 API) */
|
|
43
|
+
_registerMetadataReader(name, reader) {
|
|
44
|
+
this.metadataReaders.set(name, reader);
|
|
45
|
+
}
|
|
46
|
+
constructor(config = {}) {
|
|
47
|
+
this.config = {
|
|
48
|
+
enableOpfs: config.enableOpfs ?? true,
|
|
49
|
+
enableIndexedDB: config.enableIndexedDB ?? true,
|
|
50
|
+
storageQuota: config.storageQuota ?? 1024 * 1024 * 1024, // 1GB
|
|
51
|
+
enableLog: config.enableLog ?? true,
|
|
52
|
+
engineStrategy: config.engineStrategy ?? 'first',
|
|
53
|
+
isPro: config.isPro ?? false,
|
|
54
|
+
plan: config.plan ?? 'free',
|
|
55
|
+
memoryBudget: config.memoryBudget ?? DEFAULT_MEMORY_BUDGET,
|
|
56
|
+
};
|
|
57
|
+
this.eventBus = createEventBus();
|
|
58
|
+
// enableOpfs/enableIndexedDB 仅在 createLokvis()/createRuntime 工厂中生效
|
|
59
|
+
// (工厂按 flag 调 createAssetStore 选择 OPFS→IDB→Memory)。直接 new Impl
|
|
60
|
+
// 且未传 assetStore 时,无法同步等待 createAssetStore,兜底用 Memory store。
|
|
61
|
+
if (!config.assetStore && (this.config.enableOpfs || this.config.enableIndexedDB)) {
|
|
62
|
+
console.warn('[lokvis] LokvisRuntimeImpl constructed without assetStore: ' +
|
|
63
|
+
'enableOpfs/enableIndexedDB flags are ignored. ' +
|
|
64
|
+
'Use createLokvis() to respect these flags, or pass an assetStore explicitly.');
|
|
65
|
+
}
|
|
66
|
+
const rawStore = config.assetStore ?? createMemoryAssetStore();
|
|
67
|
+
// W21.6 + review fix: ownsAssetStore 已从公共 RuntimeConfig 移到
|
|
68
|
+
// InternalRuntimeInit,SDK 用户类型层面无法传此字段。工厂 createRuntime
|
|
69
|
+
// 在工厂创建路径下显式传 ownsAssetStore: true,注入路径下显式传 false,
|
|
70
|
+
// 并用 `ownsAssetStore: !injectedAssetStore` 覆盖用户传入的值(防止 JS
|
|
71
|
+
// 用户绕过类型系统)。Impl 信任工厂传入的 ownsAssetStore,不再做冗余守卫。
|
|
72
|
+
this.ownsAssetStore = config.ownsAssetStore ?? !config.assetStore;
|
|
73
|
+
this.assetStore = wrapAssetStoreWithQuota(rawStore, this.config.storageQuota);
|
|
74
|
+
// AssetManager:metadataReaders 由 Runtime 持有,Plugin 注册后立即可见
|
|
75
|
+
this.assetManager = new AssetManager({
|
|
76
|
+
assetStore: this.assetStore, eventBus: this.eventBus,
|
|
77
|
+
metadataReaders: this.metadataReaders,
|
|
78
|
+
storageQuota: this.config.storageQuota,
|
|
79
|
+
});
|
|
80
|
+
this.historyStore = config.historyStore;
|
|
81
|
+
this.historyManager = new HistoryManager({
|
|
82
|
+
eventBus: this.eventBus, assetStore: this.assetStore,
|
|
83
|
+
historyStore: this.historyStore,
|
|
84
|
+
});
|
|
85
|
+
this.capabilityRegistry = new CapabilityRegistry(this.config.engineStrategy);
|
|
86
|
+
this.executor = new WorkflowExecutor({
|
|
87
|
+
assetStore: this.assetStore, capabilityRegistry: this.capabilityRegistry,
|
|
88
|
+
eventBus: this.eventBus, enableLog: this.config.enableLog,
|
|
89
|
+
});
|
|
90
|
+
this.workflowCoordinator = new WorkflowCoordinator({
|
|
91
|
+
executor: this.executor, capabilityRegistry: this.capabilityRegistry,
|
|
92
|
+
eventBus: this.eventBus, historyManager: this.historyManager,
|
|
93
|
+
});
|
|
94
|
+
this.memoryGuard = new MemoryGuard({
|
|
95
|
+
budget: this.config.memoryBudget, assetStore: this.assetStore,
|
|
96
|
+
});
|
|
97
|
+
this.batchProcessor = new BatchProcessor({
|
|
98
|
+
runtime: this, eventBus: this.eventBus,
|
|
99
|
+
isPro: this.config.isPro, memoryGuard: this.memoryGuard,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
get status() { return this.workflowCoordinator.status; }
|
|
103
|
+
get isPro() { return this.config.isPro; }
|
|
104
|
+
get plan() { return this.config.plan; }
|
|
105
|
+
get batch() { return this.batchProcessor; }
|
|
106
|
+
// ─── 工作流执行(委托 WorkflowCoordinator) ──────────────
|
|
107
|
+
async run(workflow, inputs, options) {
|
|
108
|
+
if (this.disposed)
|
|
109
|
+
throw new Error('LokvisRuntime is disposed');
|
|
110
|
+
return this.workflowCoordinator.run(workflow, inputs, options);
|
|
111
|
+
}
|
|
112
|
+
async cancel(workflowId) {
|
|
113
|
+
if (this.disposed)
|
|
114
|
+
throw new Error('LokvisRuntime is disposed');
|
|
115
|
+
return this.workflowCoordinator.cancel(workflowId);
|
|
116
|
+
}
|
|
117
|
+
async pause(workflowId) {
|
|
118
|
+
if (this.disposed)
|
|
119
|
+
throw new Error('LokvisRuntime is disposed');
|
|
120
|
+
return this.workflowCoordinator.pause(workflowId);
|
|
121
|
+
}
|
|
122
|
+
async resume(workflowId) {
|
|
123
|
+
if (this.disposed)
|
|
124
|
+
throw new Error('LokvisRuntime is disposed');
|
|
125
|
+
return this.workflowCoordinator.resume(workflowId);
|
|
126
|
+
}
|
|
127
|
+
async disposeWorkflow(workflowId) {
|
|
128
|
+
if (this.disposed)
|
|
129
|
+
throw new Error('LokvisRuntime is disposed');
|
|
130
|
+
return this.workflowCoordinator.disposeWorkflow(workflowId);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 销毁整个 Runtime(W21.6)。
|
|
134
|
+
*
|
|
135
|
+
* 顺序:
|
|
136
|
+
* 1. 标记 disposed(阻止后续 run/cancel,防止清理期间新请求进入)
|
|
137
|
+
* 2. executor.cancelAll() —— 取消所有运行中 workflow 的 AbortController
|
|
138
|
+
* 3. batchProcessor.dispose() —— 标记所有非终态 job 为 cancelled + 清理订阅
|
|
139
|
+
* 4. historyManager.disposeAll() —— 清空所有历史栈(reset 触发 onEvict
|
|
140
|
+
* → assetStore.remove 回收 outputs 资产);TD-2.1 改为 await 等待
|
|
141
|
+
* persistHistory 删除 IDB 记录落地
|
|
142
|
+
* 5. 清理 metadataReaders
|
|
143
|
+
* 6. 若 ownsAssetStore(工厂创建而非注入):调用 assetStore.dispose?.()
|
|
144
|
+
* 关闭 Dexie 连接 / 清空内存 Map。注入路径由消费方自行管理。
|
|
145
|
+
*
|
|
146
|
+
* 不清理:
|
|
147
|
+
* - historyStore(由消费方注入或工厂创建,Dexie 连接由浏览器 GC 处理)
|
|
148
|
+
* - eventBus listeners(允许外部已订阅的 listener 仍收到最后一批
|
|
149
|
+
* workflow:cancelled 等事件;若需要清空可单独调 eventBus.clear)
|
|
150
|
+
*
|
|
151
|
+
* 幂等:重复调用为 no-op。
|
|
152
|
+
*/
|
|
153
|
+
async dispose() {
|
|
154
|
+
if (this.disposed)
|
|
155
|
+
return;
|
|
156
|
+
this.disposed = true;
|
|
157
|
+
// 1. 取消所有运行中 workflow(同步 abort + 唤醒 resume resolver)
|
|
158
|
+
this.executor.cancelAll();
|
|
159
|
+
// 2. 取消所有非终态 batch job + 清理 progress 订阅
|
|
160
|
+
await this.batchProcessor.dispose();
|
|
161
|
+
// 3. 清空所有历史栈(触发 outputs 资产回收);TD-2.1: await 等待持久化删除落地
|
|
162
|
+
await this.historyManager.disposeAll();
|
|
163
|
+
// 4. 清理 metadataReaders(释放插件注册的 reader 引用)
|
|
164
|
+
this.metadataReaders.clear();
|
|
165
|
+
// 5. 若 Runtime 拥有 assetStore(工厂创建),释放底层资源
|
|
166
|
+
// (注入路径由消费方自行管理生命周期,避免越权清理)
|
|
167
|
+
if (this.ownsAssetStore) {
|
|
168
|
+
await this.assetStore.dispose?.();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ─── 历史与撤销(委托 HistoryManager) ──────────────────
|
|
172
|
+
async history(workflowId) { return this.historyManager.history(workflowId); }
|
|
173
|
+
async getHistoryState(workflowId) {
|
|
174
|
+
return this.historyManager.getHistoryState(workflowId);
|
|
175
|
+
}
|
|
176
|
+
async undo(workflowId) { return this.historyManager.undo(workflowId); }
|
|
177
|
+
async redo(workflowId) { return this.historyManager.redo(workflowId); }
|
|
178
|
+
async jumpTo(workflowId, index) { return this.historyManager.jumpTo(workflowId, index); }
|
|
179
|
+
// ─── Asset 管理(委托 AssetManager) ─────────────────
|
|
180
|
+
async importAsset(source) { return this.assetManager.importAsset(source); }
|
|
181
|
+
async getAsset(id) { return this.assetManager.getAsset(id); }
|
|
182
|
+
async exportAsset(id, format) { return this.assetManager.exportAsset(id, format); }
|
|
183
|
+
async readAssetExif(id) { return this.assetManager.readAssetExif(id); }
|
|
184
|
+
async readAssetImageMetadata(id) { return this.assetManager.readAssetImageMetadata(id); }
|
|
185
|
+
async readAssetPdfInfo(id) { return this.assetManager.readAssetPdfInfo(id); }
|
|
186
|
+
async removeAsset(id) { return this.assetManager.removeAsset(id); }
|
|
187
|
+
async listAssets() { return this.assetManager.listAssets(); }
|
|
188
|
+
async getStorageUsage() { return this.assetManager.getStorageUsage(); }
|
|
189
|
+
// ─── 能力查询(委托 CapabilityRegistry) ────────────────
|
|
190
|
+
async capabilities() { return this.capabilityRegistry.list(); }
|
|
191
|
+
async hasCapability(name) { return this.capabilityRegistry.has(name); }
|
|
192
|
+
async isStubOnly(name) { return this.capabilityRegistry.isStubOnly(name); }
|
|
193
|
+
// ─── MCP 暴露(委托 mcp-manifest-builder) ──────────────
|
|
194
|
+
toMcpManifest(options = {}) {
|
|
195
|
+
return buildMcpManifest(this.capabilityRegistry.list(), options, RUNTIME_VERSION);
|
|
196
|
+
}
|
|
197
|
+
// ─── 插件安装 ────────────────────────────────────────
|
|
198
|
+
/**
|
|
199
|
+
* 安装插件:① 注册能力声明 → ② 构造权限沙箱 → ③ 构造受限 PluginContext
|
|
200
|
+
* → ④ 应用 network guard(声明 network:none 时 monkey-patch 全局
|
|
201
|
+
* fetch/XHR/WebSocket/EventSource)→ ⑤ 调用 plugin.install(ctx)
|
|
202
|
+
* → ⑥ restore 全局 API → ⑦ 发射 plugin:loaded 事件。不吞错。
|
|
203
|
+
*
|
|
204
|
+
* network guard 仅在 plugin.install() 期间生效;install 后插件若异步调用
|
|
205
|
+
* 网络 API(如 setTimeout 回调)无法覆盖 —— plugin 作者应据 ctx.sandbox
|
|
206
|
+
* 主动断言(best-effort 守卫,见 docs/PROJECT_PLAN.md W18.6)。
|
|
207
|
+
*/
|
|
208
|
+
async installPlugin(plugin) {
|
|
209
|
+
for (const capability of plugin.config.capabilities) {
|
|
210
|
+
this.capabilityRegistry.registerCapability(capability);
|
|
211
|
+
}
|
|
212
|
+
const sandbox = new PluginPermissionSandbox(plugin.config.name, plugin.config.permissions);
|
|
213
|
+
const ctx = createPluginContext(plugin.config.name, {
|
|
214
|
+
eventBus: this.eventBus, assetStore: this.assetStore,
|
|
215
|
+
capabilityRegistry: this.capabilityRegistry,
|
|
216
|
+
registerMetadataReader: (name, reader) => this._registerMetadataReader(name, reader),
|
|
217
|
+
sandbox,
|
|
218
|
+
});
|
|
219
|
+
const restore = sandbox.applyNetworkGuard();
|
|
220
|
+
try {
|
|
221
|
+
await plugin.install(ctx);
|
|
222
|
+
}
|
|
223
|
+
finally {
|
|
224
|
+
restore();
|
|
225
|
+
}
|
|
226
|
+
this.eventBus.emit({
|
|
227
|
+
type: 'plugin:loaded', name: plugin.config.name, version: plugin.config.version,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// ─── 内部 API(供测试使用,SDK 不再调用) ──────────────
|
|
231
|
+
_getAssetStore() { return this.assetStore; }
|
|
232
|
+
_getCapabilityRegistry() { return this.capabilityRegistry; }
|
|
233
|
+
_getMemoryGuard() { return this.memoryGuard; }
|
|
234
|
+
_getCurrentOutputs(workflowId) { return this.historyManager.getCurrentOutputs(workflowId); }
|
|
235
|
+
async getCurrentOutputs(workflowId) { return this._getCurrentOutputs(workflowId); }
|
|
236
|
+
/** 从 historyStore 预加载持久化历史快照(由 createRuntime 工厂在构造后调用一次,impl 初始化钩子)。 */
|
|
237
|
+
async loadPersistedHistory() { return this.historyManager.loadPersistedHistory(); }
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* 创建 Runtime 实例(W2.8 + W2.9)。默认通过 createAssetStore 工厂按 OPFS →
|
|
241
|
+
* IndexedDB → Memory 降级创建 AssetStore 并用配额校验包裹;也可通过
|
|
242
|
+
* config.assetStore 注入自定义 store。async(工厂需异步探测环境)。
|
|
243
|
+
*/
|
|
244
|
+
export async function createRuntime(config) {
|
|
245
|
+
// W21.6 + review fix: 判断 assetStore 是否由工厂创建(未注入即工厂创建)。
|
|
246
|
+
// 工厂创建的 store 由 Runtime 拥有,dispose() 时负责调用 assetStore.dispose?.()。
|
|
247
|
+
//
|
|
248
|
+
// 运行时守卫:此处的 `ownsAssetStore: !injectedAssetStore` 会覆盖 `...config`
|
|
249
|
+
// 中可能存在的 ownsAssetStore 字段(虽然 TypeScript 层面 RuntimeConfig 已不含
|
|
250
|
+
// 此字段,但 JS 用户可能绕过类型系统传入)。这样确保注入路径下 ownsAssetStore
|
|
251
|
+
// 始终为 false,防止 Runtime 越权清理注入的 store。
|
|
252
|
+
const injectedAssetStore = config?.assetStore;
|
|
253
|
+
const assetStore = injectedAssetStore ??
|
|
254
|
+
(await createAssetStore({ preferOpfs: config?.enableOpfs ?? true }));
|
|
255
|
+
// W7.2 历史持久化:优先用注入的 historyStore;否则在 enableIndexedDB 时
|
|
256
|
+
// 通过 createHistoryStore 自动创建(IDB 不可用时返回 undefined,退化仅内存)
|
|
257
|
+
const historyStore = config?.historyStore ??
|
|
258
|
+
((config?.enableIndexedDB ?? true)
|
|
259
|
+
? createHistoryStore(config?.historyStoreOptions)
|
|
260
|
+
: undefined);
|
|
261
|
+
const impl = new LokvisRuntimeImpl({
|
|
262
|
+
...config,
|
|
263
|
+
assetStore,
|
|
264
|
+
historyStore,
|
|
265
|
+
ownsAssetStore: !injectedAssetStore,
|
|
266
|
+
});
|
|
267
|
+
await impl.loadPersistedHistory(); // 预加载持久化历史快照(跨会话恢复 undo/redo 链)
|
|
268
|
+
return impl;
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=runtime-impl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-impl.js","sourceRoot":"","sources":["../src/runtime-impl.ts"],"names":[],"mappings":"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"}
|