@lark.js/mvc 0.0.15 → 0.0.17
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 +324 -215
- package/dist/chunk-OGPBFCIK.js +105 -0
- package/dist/client.d.cts +63 -0
- package/dist/client.d.ts +10 -34
- package/dist/compiler.cjs +15534 -15854
- package/dist/compiler.d.cts +1 -1
- package/dist/compiler.d.ts +1 -1
- package/dist/compiler.js +15519 -15851
- package/dist/devtool.cjs +2617 -4152
- package/dist/devtool.d.cts +1 -2
- package/dist/devtool.d.ts +1 -2
- package/dist/devtool.js +2543 -4159
- package/dist/index.cjs +4128 -6008
- package/dist/index.d.cts +571 -1291
- package/dist/index.d.ts +571 -1291
- package/dist/index.js +4058 -5976
- package/dist/rspack.cjs +15648 -15935
- package/dist/rspack.d.cts +8 -45
- package/dist/rspack.d.ts +8 -45
- package/dist/rspack.js +15641 -15934
- package/dist/runtime.cjs +79 -79
- package/dist/runtime.js +19 -85
- package/dist/vite.cjs +15841 -15957
- package/dist/vite.d.cts +6 -7
- package/dist/vite.d.ts +6 -7
- package/dist/vite.js +15834 -15955
- package/dist/webpack.cjs +15648 -15985
- package/dist/webpack.d.cts +5 -33
- package/dist/webpack.d.ts +5 -33
- package/dist/webpack.js +15641 -15984
- package/package.json +3 -4
- package/dist/apply-style.d.ts +0 -9
- package/dist/cache.d.ts +0 -69
- package/dist/common.d.ts +0 -64
- package/dist/compiler/compile-template.d.ts +0 -16
- package/dist/compiler/compile-to-vdom-function.d.ts +0 -13
- package/dist/compiler/extract-global-vars.d.ts +0 -17
- package/dist/compiler/template-syntax.d.ts +0 -61
- package/dist/cross-site.d.ts +0 -29
- package/dist/dom.d.ts +0 -45
- package/dist/event-delegator.d.ts +0 -28
- package/dist/event-emitter.d.ts +0 -38
- package/dist/frame.d.ts +0 -143
- package/dist/framework.d.ts +0 -9
- package/dist/hmr.d.ts +0 -53
- package/dist/index.amd.js +0 -6285
- package/dist/index.umd.js +0 -6272
- package/dist/mark.d.ts +0 -26
- package/dist/module-loader.d.ts +0 -20
- package/dist/router.d.ts +0 -14
- package/dist/runtime.amd.js +0 -94
- package/dist/runtime.umd.js +0 -98
- package/dist/service.d.ts +0 -173
- package/dist/state.d.ts +0 -8
- package/dist/store.d.ts +0 -60
- package/dist/types.d.ts +0 -1259
- package/dist/updater.d.ts +0 -90
- package/dist/url-state.d.ts +0 -32
- package/dist/utils.d.ts +0 -90
- package/dist/vdom.d.ts +0 -45
- package/dist/view-registry.d.ts +0 -20
- package/dist/view.d.ts +0 -214
package/dist/index.d.ts
CHANGED
|
@@ -26,16 +26,6 @@ declare const CALL_BREAK_TIME = 48;
|
|
|
26
26
|
/** Increment global counter and return new value */
|
|
27
27
|
declare function nextCounter(): number;
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* Dynamically inject CSS styles into the document head.
|
|
31
|
-
* Returns a cleanup function to remove the injected styles.
|
|
32
|
-
*
|
|
33
|
-
* @param styleIdOrPairs - Style ID string or array of [id, content] pairs
|
|
34
|
-
* @param css - CSS content string (only used when first arg is string)
|
|
35
|
-
* @returns Cleanup function to remove the styles
|
|
36
|
-
*/
|
|
37
|
-
declare function applyStyle(styleIdOrPairs: string | string[], css?: string): () => void;
|
|
38
|
-
|
|
39
29
|
/**
|
|
40
30
|
* Mark/Unmark: signature-based lifecycle tracking for async callbacks.
|
|
41
31
|
*
|
|
@@ -64,444 +54,77 @@ declare function mark(host: object, key: string): () => boolean;
|
|
|
64
54
|
declare function unmark(host: object): void;
|
|
65
55
|
|
|
66
56
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* @example
|
|
70
|
-
* const emitter = new EventEmitter();
|
|
71
|
-
* emitter.on('change', (data) => console.log(data));
|
|
72
|
-
* emitter.fire('change', { key: 'value' });
|
|
73
|
-
*/
|
|
74
|
-
declare class EventEmitter<T = unknown> implements EventEmitterInterface<T> {
|
|
75
|
-
/** Event listeners: prefixed key -> listener array */
|
|
76
|
-
listeners: Map<string, EventListenerEntry[]>;
|
|
77
|
-
/** Number of `fire()` calls currently on the stack (re-entrancy depth). */
|
|
78
|
-
private firingDepth;
|
|
79
|
-
/** Keys whose listener list needs compaction after firing settles. */
|
|
80
|
-
private pendingCompaction;
|
|
81
|
-
/**
|
|
82
|
-
* Bind event listener.
|
|
83
|
-
*/
|
|
84
|
-
on(event: string, handler: (this: T, e: ChangeEvent) => void): this;
|
|
85
|
-
/**
|
|
86
|
-
* Unbind event listener.
|
|
87
|
-
* If handler is provided, removes only that handler.
|
|
88
|
-
* If no handler, removes all handlers for the event.
|
|
89
|
-
*/
|
|
90
|
-
off(event: string, handler?: AnyFunc): this;
|
|
91
|
-
/**
|
|
92
|
-
* Fire event, execute all bound handlers. Safe for re-entrant `off()` calls
|
|
93
|
-
* during dispatch: removed handlers are replaced with noop and compacted
|
|
94
|
-
* after the outermost fire returns.
|
|
95
|
-
*
|
|
96
|
-
* @param event - Event name
|
|
97
|
-
* @param data - Event data (type property added automatically)
|
|
98
|
-
* @param remove - Whether to remove all handlers after firing
|
|
99
|
-
* @param lastToFirst - Whether to execute handlers in reverse order
|
|
100
|
-
*/
|
|
101
|
-
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Minimal HMR context interface.
|
|
106
|
-
* Compatible with Vite's `import.meta.hot` and webpack's `module.hot`.
|
|
107
|
-
* Defined here to avoid depending on bundler-specific type packages.
|
|
57
|
+
* Register a View setup function for a given view path.
|
|
58
|
+
* Called after module loading completes (or up front during boot).
|
|
108
59
|
*/
|
|
109
|
-
|
|
110
|
-
/** Accept a self-update. The callback receives the new module namespace. */
|
|
111
|
-
accept(cb?: (mod: {
|
|
112
|
-
default?: unknown;
|
|
113
|
-
} | undefined) => void): void;
|
|
114
|
-
/** Register a cleanup callback that runs before this module is replaced. */
|
|
115
|
-
dispose(cb: (data: unknown) => void): void;
|
|
116
|
-
/** Force a full page reload (fallback when HMR cannot handle the update). */
|
|
117
|
-
invalidate(): void;
|
|
118
|
-
}
|
|
60
|
+
declare function registerViewClass(viewPath: string, setup: ViewSetup): void;
|
|
119
61
|
/**
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* After a new View class is registered via `registerViewClass`, calling this
|
|
124
|
-
* function triggers `frame.mountView()` on each matching frame. Since the new
|
|
125
|
-
* class is already in the registry, `Frame.mountView` takes the synchronous
|
|
126
|
-
* path (`getViewClass` returns the class immediately).
|
|
127
|
-
*
|
|
128
|
-
* @param viewPath - The view path to match (e.g. 'home', 'components/list')
|
|
62
|
+
* Invalidate a View setup from the registry.
|
|
63
|
+
* Used by HMR to force re-loading of a view module.
|
|
129
64
|
*/
|
|
130
|
-
declare function
|
|
65
|
+
declare function invalidateViewClass(viewPath: string): void;
|
|
131
66
|
|
|
132
67
|
/**
|
|
133
|
-
*
|
|
134
|
-
*
|
|
68
|
+
* Create a frame object. Called internally by mountFrame / createRoot.
|
|
69
|
+
* Not intended for direct user use — use `Frame.createRoot()` or
|
|
70
|
+
* `frame.mountFrame()` instead.
|
|
71
|
+
*
|
|
72
|
+
* @internal
|
|
135
73
|
*/
|
|
136
|
-
declare
|
|
137
|
-
|
|
138
|
-
id: string;
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/** Whether rendered at least once */
|
|
146
|
-
rendered?: boolean;
|
|
147
|
-
/** Whether view has template */
|
|
148
|
-
template?: ViewTemplate;
|
|
149
|
-
/** Location observation config */
|
|
150
|
-
locationObserved: ViewLocationObserved;
|
|
151
|
-
/** Observed state keys */
|
|
152
|
-
observedStateKeys?: string[];
|
|
153
|
-
/** Resource map */
|
|
154
|
-
resources: Record<string, ViewResourceEntry>;
|
|
155
|
-
/** Whether endUpdate pending */
|
|
156
|
-
endUpdatePending?: number;
|
|
157
|
-
/** Internal event storage */
|
|
158
|
-
private _events;
|
|
159
|
-
/** Prototype-stored event maps shape (set by View.prepare). */
|
|
160
|
-
private get protoEventState();
|
|
161
|
-
/**
|
|
162
|
-
* Event bitmask map: eventType -> bitmask (1=root, 2=selector).
|
|
163
|
-
* Read from prototype ($evtObjMap) set by View.prepare.
|
|
164
|
-
* Using a getter avoids ES6 class field shadowing the prototype value.
|
|
165
|
-
*/
|
|
166
|
-
get eventObjectMap(): Record<string, number>;
|
|
167
|
-
/**
|
|
168
|
-
* Selector event map: eventType -> selector list.
|
|
169
|
-
* Read from prototype ($selMap) set by View.prepare.
|
|
170
|
-
*/
|
|
171
|
-
get eventSelectorMap(): Record<string, ViewEventSelectorEntry>;
|
|
172
|
-
/**
|
|
173
|
-
* Global event list: [{handler, element, eventName, modifiers}].
|
|
174
|
-
* Read from prototype ($globalEvtList) set by View.prepare.
|
|
175
|
-
*/
|
|
176
|
-
get globalEventList(): ViewGlobalEventEntry[];
|
|
177
|
-
/**
|
|
178
|
-
* Initialize view (called by Frame when mounting).
|
|
179
|
-
*/
|
|
180
|
-
init(): void;
|
|
181
|
-
/**
|
|
182
|
-
* Render view template (called by Frame after init).
|
|
183
|
-
* Wrapped by View.wrapMethod to manage signature + resources.
|
|
184
|
-
*/
|
|
185
|
-
render(): void;
|
|
186
|
-
on(event: string, handler: AnyFunc): this;
|
|
187
|
-
off(event: string, handler?: AnyFunc): this;
|
|
188
|
-
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
189
|
-
/** Get the owning frame, asserting it has been bound. */
|
|
190
|
-
private get ownerFrame();
|
|
191
|
-
/**
|
|
192
|
-
* Notify view that HTML update is about to begin.
|
|
193
|
-
* Unmounts child frames in the update zone.
|
|
194
|
-
*/
|
|
195
|
-
beginUpdate(id?: string): void;
|
|
196
|
-
/**
|
|
197
|
-
* Notify view that HTML update has ended.
|
|
198
|
-
* Mounts child frames in the update zone and runs deferred invokes.
|
|
199
|
-
*/
|
|
200
|
-
endUpdate(id?: string, inner?: boolean): void;
|
|
201
|
-
/**
|
|
202
|
-
* Wrap an async callback to check view signature before executing.
|
|
203
|
-
* If the view has been re-rendered or destroyed, the callback is skipped.
|
|
204
|
-
*/
|
|
205
|
-
wrapAsync<Fn extends AnyFunc>(fn: Fn, context?: unknown): (...args: Parameters<Fn>) => ReturnType<Fn> | undefined;
|
|
206
|
-
/**
|
|
207
|
-
* Observe location parameters or path changes.
|
|
208
|
-
* When observed keys change, render() is called automatically.
|
|
209
|
-
*/
|
|
210
|
-
observeLocation(params: string | string[] | Record<string, unknown>, observePath?: boolean): void;
|
|
211
|
-
/**
|
|
212
|
-
* Observe State data keys for changes.
|
|
213
|
-
* When observed keys change via State.digest(), render() is called.
|
|
214
|
-
*/
|
|
215
|
-
observeState(observedKeys: string | string[]): void;
|
|
216
|
-
/**
|
|
217
|
-
* Capture (register) a resource under a key.
|
|
218
|
-
* If a resource already exists at that key, it's destroyed first.
|
|
219
|
-
* When destroyOnRender=true, the resource is destroyed on next render call.
|
|
220
|
-
*/
|
|
221
|
-
capture(key: string, resource?: unknown, destroyOnRender?: boolean): unknown;
|
|
222
|
-
/**
|
|
223
|
-
* Release a captured resource.
|
|
224
|
-
* If destroy=true, calls the resource's destroy() method.
|
|
225
|
-
*/
|
|
226
|
-
release(key: string, destroy?: boolean): unknown;
|
|
227
|
-
/**
|
|
228
|
-
* Set up a leave confirmation for route changes and page unload.
|
|
229
|
-
*/
|
|
230
|
-
leaveTip(message: string, condition: () => boolean): void;
|
|
231
|
-
/** Collected ctors from mixins */
|
|
232
|
-
static ctors?: AnyFunc[];
|
|
233
|
-
/**
|
|
234
|
-
* Prepare a View subclass by scanning its prototype for event method patterns.
|
|
235
|
-
* Pattern: `$?name<eventType1,eventType2>(&modifiers)`
|
|
236
|
-
*
|
|
237
|
-
* Only runs once per View subclass (guarded by ctors marker).
|
|
238
|
-
* Called from Frame.mountView before creating the view instance.
|
|
239
|
-
*/
|
|
240
|
-
static prepare(oView: typeof View): AnyFunc[];
|
|
241
|
-
/**
|
|
242
|
-
* Bind or unbind event delegation for a view instance.
|
|
243
|
-
* Called from Frame during mount/unmount.
|
|
244
|
-
*/
|
|
245
|
-
static delegateEvents(view: ViewInterface, destroy?: boolean): void;
|
|
246
|
-
/**
|
|
247
|
-
* Destroy all resources managed by a view.
|
|
248
|
-
* If lastly=true, destroy ALL resources; otherwise only destroyOnRender ones.
|
|
249
|
-
*/
|
|
250
|
-
static destroyAllResources(view: ViewInterface, lastly: boolean): void;
|
|
251
|
-
/**
|
|
252
|
-
* Process deferred invoke calls on a frame.
|
|
253
|
-
*/
|
|
254
|
-
static runInvokes(frame: FrameInterface): void;
|
|
255
|
-
/**
|
|
256
|
-
* Wrap a method on the prototype to add signature checking and resource cleanup.
|
|
257
|
-
*/
|
|
258
|
-
private static wrapMethod;
|
|
259
|
-
/**
|
|
260
|
-
* When two mixins define the same event method, merge them into
|
|
261
|
-
* a single function that calls both in sequence.
|
|
262
|
-
*/
|
|
263
|
-
private static processMixinsSameEvent;
|
|
264
|
-
/**
|
|
265
|
-
* Merge an array of mixin objects into the view prototype.
|
|
266
|
-
*/
|
|
267
|
-
private static mergeMixins;
|
|
268
|
-
/**
|
|
269
|
-
* Destroy a single resource entry.
|
|
270
|
-
*/
|
|
271
|
-
private static destroyResource;
|
|
272
|
-
/**
|
|
273
|
-
* Extend View to create a new View subclass.
|
|
274
|
-
*
|
|
275
|
-
* Supports:
|
|
276
|
-
* - props.ctor: constructor-like init (called with initParams + {node, deep})
|
|
277
|
-
* - props.mixins: array of mixin objects
|
|
278
|
-
* - Event method patterns: `'name<click>'` etc.
|
|
279
|
-
*/
|
|
280
|
-
static extend(props?: ThisType<ViewInterface> & Record<string, unknown>, statics?: Record<string, unknown>): typeof View;
|
|
281
|
-
/**
|
|
282
|
-
* Merge mixins into View prototype.
|
|
283
|
-
*/
|
|
284
|
-
static merge(this: typeof View, ...mixins: Record<string, unknown>[]): typeof View;
|
|
285
|
-
/**
|
|
286
|
-
* Set up HMR accept handler for this view module.
|
|
287
|
-
*
|
|
288
|
-
* When the module is hot-replaced, the new View class is extracted from
|
|
289
|
-
* the new module, registered in the view registry, and all currently
|
|
290
|
-
* mounted frames using this viewPath are re-mounted.
|
|
291
|
-
*
|
|
292
|
-
* No-op when `hot` is undefined (production / non-HMR environment).
|
|
293
|
-
*
|
|
294
|
-
* ```ts
|
|
295
|
-
* if (import.meta.hot) {
|
|
296
|
-
* HomeView.accept(import.meta.hot, 'home');
|
|
297
|
-
* }
|
|
298
|
-
* ```
|
|
299
|
-
*/
|
|
300
|
-
static accept(hot: HotContext | undefined, viewPath: string): void;
|
|
301
|
-
/**
|
|
302
|
-
* Set up HMR dispose handler for this view module.
|
|
303
|
-
*
|
|
304
|
-
* When the module is about to be replaced, the old View class is removed
|
|
305
|
-
* from the registry so subsequent lookups don't return the stale class.
|
|
306
|
-
*
|
|
307
|
-
* No-op when `hot` is undefined (production / non-HMR environment).
|
|
308
|
-
*
|
|
309
|
-
* ```ts
|
|
310
|
-
* if (import.meta.hot) {
|
|
311
|
-
* HomeView.dispose(import.meta.hot, 'home');
|
|
312
|
-
* }
|
|
313
|
-
* ```
|
|
314
|
-
*/
|
|
315
|
-
static dispose(hot: HotContext | undefined, viewPath: string): void;
|
|
74
|
+
declare function createFrame(id: string, parentId?: string): FrameObj;
|
|
75
|
+
interface FrameApi {
|
|
76
|
+
get(id: string): FrameObj | undefined;
|
|
77
|
+
getAll(): Map<string, FrameObj>;
|
|
78
|
+
getRoot(): FrameObj | undefined;
|
|
79
|
+
createRoot(rootId?: string): FrameObj;
|
|
80
|
+
on(event: string, handler: AnyFunc): FrameApi;
|
|
81
|
+
off(event: string, handler?: AnyFunc): FrameApi;
|
|
82
|
+
fire(event: string, data?: Record<string, unknown>): void;
|
|
316
83
|
}
|
|
84
|
+
declare const Frame: FrameApi;
|
|
85
|
+
|
|
317
86
|
/**
|
|
318
|
-
*
|
|
87
|
+
* Define a view via a setup function (hooks style).
|
|
319
88
|
*
|
|
320
|
-
*
|
|
321
|
-
* `
|
|
322
|
-
*
|
|
323
|
-
* every call site.
|
|
89
|
+
* The setup function runs once on mount, receives a `ViewCtx`, and returns
|
|
90
|
+
* `{ template, events, assign? }`. Hooks (`useState`, `useEffect`, etc.)
|
|
91
|
+
* can be called inside setup to manage state and side effects.
|
|
324
92
|
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
*
|
|
328
|
-
*
|
|
329
|
-
*
|
|
330
|
-
*
|
|
331
|
-
*
|
|
332
|
-
* this.updater.set({ title: this.$title }); // both typed
|
|
333
|
-
* },
|
|
334
|
-
* greet() {
|
|
335
|
-
* return `hello ${this.$title}`;
|
|
336
|
-
* },
|
|
93
|
+
* @example
|
|
94
|
+
* const HomeView = defineView((ctx, params) => {
|
|
95
|
+
* const [getCount, setCount] = useState('count', 0);
|
|
96
|
+
* return {
|
|
97
|
+
* template,
|
|
98
|
+
* events: { "incr<click>": (e) => setCount(getCount() + 1) },
|
|
99
|
+
* };
|
|
337
100
|
* });
|
|
338
|
-
* ```
|
|
339
|
-
*
|
|
340
|
-
* Runtime semantics are identical to `View.extend(props, statics)` — this is
|
|
341
|
-
* a zero-cost type-only wrapper.
|
|
342
|
-
*/
|
|
343
|
-
declare function defineView<P extends Record<string, unknown>>(props: P & ThisType<P & ViewInterface>, statics?: Record<string, unknown>): typeof View;
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Register a View class for a given view path.
|
|
347
|
-
* Called after module loading completes (or up front during boot).
|
|
348
|
-
*/
|
|
349
|
-
declare function registerViewClass(viewPath: string, ViewClass: typeof View): void;
|
|
350
|
-
/**
|
|
351
|
-
* Invalidate a View class from the registry.
|
|
352
|
-
* Used by HMR to force re-loading of a view module.
|
|
353
101
|
*/
|
|
354
|
-
declare function
|
|
102
|
+
declare function defineView(setup: ViewSetup): ViewSetup;
|
|
355
103
|
|
|
356
104
|
/**
|
|
357
|
-
*
|
|
358
|
-
*
|
|
105
|
+
* Create a multi-cast event emitter.
|
|
106
|
+
*
|
|
107
|
+
* @returns An emitter API object with `on`, `off`, `fire` methods.
|
|
108
|
+
* The object also supports the `on{EventName}` convention: setting
|
|
109
|
+
* `emitter.onDestroy = fn` causes `fire("destroy", ...)` to call `fn`.
|
|
359
110
|
*
|
|
111
|
+
* @example
|
|
112
|
+
* const emitter = createEmitter();
|
|
113
|
+
* emitter.on('change', (data) => console.log(data));
|
|
114
|
+
* emitter.fire('change', { key: 'value' });
|
|
360
115
|
*/
|
|
361
|
-
declare
|
|
362
|
-
/** Frame ID (same as owner DOM element ID) */
|
|
363
|
-
readonly id: string;
|
|
364
|
-
/** Parent Frame ID */
|
|
365
|
-
private _parentId;
|
|
366
|
-
get parentId(): string | undefined;
|
|
367
|
-
/** Children map: id -> id */
|
|
368
|
-
childrenMap: Record<string, string>;
|
|
369
|
-
/** Children count */
|
|
370
|
-
childrenCount: number;
|
|
371
|
-
/** Ready count (children that have fired 'created') */
|
|
372
|
-
readyCount: number;
|
|
373
|
-
/** Set of child frame IDs that have fired 'created' */
|
|
374
|
-
readyMap: Set<string>;
|
|
375
|
-
/** View instance */
|
|
376
|
-
viewInstance?: ViewInterface;
|
|
377
|
-
/** Get view instance (read-only) */
|
|
378
|
-
get view(): ViewInterface | undefined;
|
|
379
|
-
/** Invoke list for deferred method calls */
|
|
380
|
-
invokeList: FrameInvokeEntry[];
|
|
381
|
-
/** Signature for async operation tracking */
|
|
382
|
-
signature: number;
|
|
383
|
-
/** Whether view has altered */
|
|
384
|
-
hasAltered: number;
|
|
385
|
-
/** Whether view is destroyed */
|
|
386
|
-
destroyed: number;
|
|
387
|
-
/** View path (v-lark attribute value) */
|
|
388
|
-
viewPath?: string;
|
|
389
|
-
/** Original template before mount */
|
|
390
|
-
originalTemplate?: string;
|
|
391
|
-
/** Hold fire created flag */
|
|
392
|
-
holdFireCreated: number;
|
|
393
|
-
/** Children created flag */
|
|
394
|
-
childrenCreated: number;
|
|
395
|
-
/** Children alter flag */
|
|
396
|
-
childrenAlter: number;
|
|
397
|
-
constructor(id: string, parentId?: string);
|
|
398
|
-
/**
|
|
399
|
-
* Mount a view to this frame.
|
|
400
|
-
*
|
|
401
|
-
* Complete flow:
|
|
402
|
-
* 1. Parse viewPath, translate query params from parent
|
|
403
|
-
* 2. Unmount current view
|
|
404
|
-
* 3. Load View class (via require or provided ViewClass)
|
|
405
|
-
* 4. View_Prepare (scan event methods)
|
|
406
|
-
* 5. Create View instance
|
|
407
|
-
* 6. View_DelegateEvents (bind DOM events)
|
|
408
|
-
* 7. Call view.init()
|
|
409
|
-
* 8. If view has template, call render via Updater
|
|
410
|
-
* 9. If no template, call endUpdate directly
|
|
411
|
-
*/
|
|
412
|
-
mountView(viewPath: string, viewInitParams?: Record<string, unknown>): void;
|
|
413
|
-
/**
|
|
414
|
-
* Internal: actually mount the view after class is loaded.
|
|
415
|
-
*/
|
|
416
|
-
doMountView(ViewClass: typeof View, params: Record<string, unknown>, node: HTMLElement, sign: number): void;
|
|
417
|
-
/**
|
|
418
|
-
* Unmount current view.
|
|
419
|
-
*/
|
|
420
|
-
unmountView(): void;
|
|
421
|
-
/**
|
|
422
|
-
* Mount a child frame.
|
|
423
|
-
*/
|
|
424
|
-
mountFrame(frameId: string, viewPath: string, viewInitParams?: Record<string, unknown>): FrameInterface;
|
|
425
|
-
/**
|
|
426
|
-
* Unmount a child frame.
|
|
427
|
-
*/
|
|
428
|
-
unmountFrame(id?: string): void;
|
|
429
|
-
/**
|
|
430
|
-
* Mount all views in a zone.
|
|
431
|
-
*/
|
|
432
|
-
mountZone(zoneId?: string): void;
|
|
433
|
-
/**
|
|
434
|
-
* Unmount all views in a zone.
|
|
435
|
-
*/
|
|
436
|
-
unmountZone(zoneId?: string): void;
|
|
437
|
-
/**
|
|
438
|
-
* Get all child frame IDs.
|
|
439
|
-
*/
|
|
440
|
-
children(): string[];
|
|
441
|
-
/**
|
|
442
|
-
* Get parent frame at given level.
|
|
443
|
-
* @param level - How many levels up (default 1)
|
|
444
|
-
*/
|
|
445
|
-
parent(level?: number): Frame | undefined;
|
|
446
|
-
/**
|
|
447
|
-
* Invoke a method on the view.
|
|
448
|
-
*/
|
|
449
|
-
invoke(name: string, args?: unknown[]): unknown;
|
|
450
|
-
/**
|
|
451
|
-
* Type-safe variant of `invoke`.
|
|
452
|
-
*
|
|
453
|
-
* `invoke()` accepts any string and any args, which silently hides
|
|
454
|
-
* mismatched call sites when a method gets renamed. `invokeTyped` carries
|
|
455
|
-
* the view's method signature through TypeScript so the compiler catches
|
|
456
|
-
* those mistakes:
|
|
457
|
-
*
|
|
458
|
-
* ```ts
|
|
459
|
-
* type Home = View & { loadData(id: string): Promise<void> };
|
|
460
|
-
* frame.invokeTyped<Home, "loadData">("loadData", ["user-1"]);
|
|
461
|
-
* ```
|
|
462
|
-
*
|
|
463
|
-
* Behavior is identical to `invoke` at runtime — same defer / direct-call
|
|
464
|
-
* paths — so it's a drop-in safer overload.
|
|
465
|
-
*/
|
|
466
|
-
invokeTyped<V extends Record<string, unknown>, K extends keyof V & string>(name: K, args: V[K] extends (...a: infer A) => unknown ? A : never[]): V[K] extends (...a: never[]) => infer R ? R | undefined : unknown;
|
|
467
|
-
/** Get frame by ID */
|
|
468
|
-
static get(id: string): Frame | undefined;
|
|
469
|
-
/** Get all frames */
|
|
470
|
-
static getAll(): Map<string, Frame>;
|
|
471
|
-
/**
|
|
472
|
-
* Returns the existing root frame, or `undefined` if none has been created.
|
|
473
|
-
* Pure getter — never creates a Frame, never touches the DOM.
|
|
474
|
-
*
|
|
475
|
-
* Use `Frame.createRoot(id)` to create the root explicitly during framework
|
|
476
|
-
* boot. For Micro-Frontend hosts that own multiple independent containers,
|
|
477
|
-
* use `new Frame(containerId)` directly so each MF mount has its own root.
|
|
478
|
-
*/
|
|
479
|
-
static getRoot(): Frame | undefined;
|
|
480
|
-
/**
|
|
481
|
-
* Create (or return) the singleton root frame for this app.
|
|
482
|
-
*
|
|
483
|
-
* Idempotent: subsequent calls always return the original root regardless
|
|
484
|
-
* of `rootId` — so passing a different id later is silently ignored.
|
|
485
|
-
* `Framework.boot()` is the canonical caller; user code rarely needs this.
|
|
486
|
-
*/
|
|
487
|
-
static createRoot(rootId?: string): Frame;
|
|
488
|
-
/** Bind event listener (static) */
|
|
489
|
-
static on(event: string, handler: AnyFunc): typeof Frame;
|
|
490
|
-
/** Unbind event listener (static) */
|
|
491
|
-
static off(event: string, handler?: AnyFunc): typeof Frame;
|
|
492
|
-
/** Fire event (static) */
|
|
493
|
-
static fire(event: string, data?: Record<string, unknown>): void;
|
|
494
|
-
}
|
|
116
|
+
declare function createEmitter<T = unknown>(): EmitterApi<T>;
|
|
495
117
|
|
|
496
118
|
/**
|
|
497
119
|
* Lark framework type definitions.
|
|
498
|
-
* All shared types are defined here to
|
|
120
|
+
* All shared types are defined here to provide a single source of truth
|
|
121
|
+
* for module interfaces and to enforce type safety across the framework.
|
|
499
122
|
*
|
|
500
123
|
* Lark is a lightweight MVC frontend framework that provides:
|
|
501
|
-
* - View:
|
|
502
|
-
* - Router: hash
|
|
124
|
+
* - View: functional view system via defineView() + ViewCtx + Hooks
|
|
125
|
+
* - Router: history/hash two-phase route confirmation
|
|
503
126
|
* - State: simple cross-view observable singleton (recommended for simple cases)
|
|
504
|
-
* - Store: zustand-aligned state management with
|
|
127
|
+
* - Store: zustand-aligned state management with createStore/getState/setState/subscribe
|
|
505
128
|
* (recommended for complex cases)
|
|
506
129
|
* - Service: API request management with caching, queuing, and deduplication
|
|
507
130
|
* - Frame: view frame managing view mount/unmount lifecycle
|
|
@@ -536,48 +159,6 @@ interface CacheOptions<T> {
|
|
|
536
159
|
/** Comparator for sorting entries */
|
|
537
160
|
sortComparator?: (a: CacheEntry<T>, b: CacheEntry<T>) => number;
|
|
538
161
|
}
|
|
539
|
-
/**
|
|
540
|
-
* Cache interface providing LFU (Least Frequently Used) cache management.
|
|
541
|
-
* Cache keys use a special prefix internally for namespace isolation.
|
|
542
|
-
*/
|
|
543
|
-
interface CacheInterface<T = unknown> {
|
|
544
|
-
/**
|
|
545
|
-
* Set a cache resource. If the key exists, updates the value and increments frequency.
|
|
546
|
-
* Triggers LFU eviction when cache entries exceed capacity (maxSize + bufferSize).
|
|
547
|
-
* @param key Unique identifier for the cached resource
|
|
548
|
-
* @param resource The resource to cache
|
|
549
|
-
*/
|
|
550
|
-
set(key: string, resource: T): void;
|
|
551
|
-
/**
|
|
552
|
-
* Get a cached resource. Access increments frequency count and timestamp for LFU ranking.
|
|
553
|
-
* Returns undefined if the key does not exist.
|
|
554
|
-
* @param key Cache resource key
|
|
555
|
-
*/
|
|
556
|
-
get(key: string): T | undefined;
|
|
557
|
-
/**
|
|
558
|
-
* Remove a resource from cache by key. Triggers onRemove callback on deletion.
|
|
559
|
-
* @param key Cache resource key to remove
|
|
560
|
-
*/
|
|
561
|
-
del(key: string): void;
|
|
562
|
-
/**
|
|
563
|
-
* Check if cache contains a resource for the given key.
|
|
564
|
-
* @param key Cache resource key
|
|
565
|
-
*/
|
|
566
|
-
has(key: string): boolean;
|
|
567
|
-
/**
|
|
568
|
-
* Iterate over all cached resource values.
|
|
569
|
-
* @param callback Iteration callback receiving the cached value (may be undefined)
|
|
570
|
-
*/
|
|
571
|
-
forEach(callback: (value: T | undefined) => void): void;
|
|
572
|
-
/**
|
|
573
|
-
* Number of cache entries.
|
|
574
|
-
*/
|
|
575
|
-
readonly size: number;
|
|
576
|
-
/**
|
|
577
|
-
* Clear all cache entries. Triggers onRemove callback for each deleted entry.
|
|
578
|
-
*/
|
|
579
|
-
clear(): void;
|
|
580
|
-
}
|
|
581
162
|
interface EventListenerEntry {
|
|
582
163
|
/** Handler function */
|
|
583
164
|
handler: AnyFunc;
|
|
@@ -691,7 +272,7 @@ interface DomRef {
|
|
|
691
272
|
/** ID update list: [element, newId][] */
|
|
692
273
|
idUpdates: [Element, string][];
|
|
693
274
|
/** Views that need post-processing */
|
|
694
|
-
views:
|
|
275
|
+
views: ViewCtx[];
|
|
695
276
|
/** DOM operation list: [opCode, parent, newChild?, oldChild?][] */
|
|
696
277
|
domOps: DomOp[];
|
|
697
278
|
/** Whether anything changed */
|
|
@@ -748,7 +329,7 @@ interface VDomRef {
|
|
|
748
329
|
/** View ID (for placeholder replacement) */
|
|
749
330
|
viewId: string;
|
|
750
331
|
/** Sub-views that need re-rendering after diff */
|
|
751
|
-
viewRenders:
|
|
332
|
+
viewRenders: ViewCtx[];
|
|
752
333
|
/** Deferred DOM property assignments: [element, propName, value][] */
|
|
753
334
|
nodeProps: [Element, string, unknown][];
|
|
754
335
|
/** Pending async operation count */
|
|
@@ -776,20 +357,6 @@ interface FrameInvokeEntry {
|
|
|
776
357
|
/** Whether removed (args match) */
|
|
777
358
|
removed?: boolean;
|
|
778
359
|
}
|
|
779
|
-
/** Mixin event handler with internal merge marker and handler list */
|
|
780
|
-
interface MixinEventHandler extends AnyFunc {
|
|
781
|
-
/** Merged handler list */
|
|
782
|
-
handlerList?: AnyFunc[];
|
|
783
|
-
/** Mixin marker: 1 = this is a mixin function */
|
|
784
|
-
marker?: number;
|
|
785
|
-
}
|
|
786
|
-
/** View event selector map entry: handler name list with selector presence tracking */
|
|
787
|
-
interface ViewEventSelectorEntry {
|
|
788
|
-
/** Selector name list */
|
|
789
|
-
selectors: string[];
|
|
790
|
-
/** Index signature for checking if selector is already registered */
|
|
791
|
-
[selector: string]: unknown;
|
|
792
|
-
}
|
|
793
360
|
/**
|
|
794
361
|
* Compiled template function signature.
|
|
795
362
|
* `data`/`viewId`/`refData` are required; subsequent encoder args are
|
|
@@ -810,18 +377,6 @@ interface ViewResourceEntry {
|
|
|
810
377
|
/** Whether to destroy when render() is called */
|
|
811
378
|
destroyOnRender: boolean;
|
|
812
379
|
}
|
|
813
|
-
interface ViewGlobalEventEntry {
|
|
814
|
-
/** Handler function */
|
|
815
|
-
handler: AnyFunc;
|
|
816
|
-
/** Bound handler wrapper (for removeEventListener) */
|
|
817
|
-
boundHandler?: AnyFunc;
|
|
818
|
-
/** DOM element (window/document) */
|
|
819
|
-
element: EventTarget;
|
|
820
|
-
/** Event name */
|
|
821
|
-
eventName: string;
|
|
822
|
-
/** Modifiers */
|
|
823
|
-
modifiers: Record<string, boolean>;
|
|
824
|
-
}
|
|
825
380
|
/**
|
|
826
381
|
* View configuration for listening to URL changes.
|
|
827
382
|
* Used as object parameter for `observeLocation()` method.
|
|
@@ -841,7 +396,13 @@ interface ViewObserveLocation {
|
|
|
841
396
|
* Supports two-phase route confirmation mechanism: change (can reject) → changed.
|
|
842
397
|
* Hash-based implementation using #! as default hash prefix.
|
|
843
398
|
*/
|
|
844
|
-
interface
|
|
399
|
+
interface RouterApi {
|
|
400
|
+
/** Bind event listener */
|
|
401
|
+
on(event: string, handler: (e?: ChangeEvent) => void): this;
|
|
402
|
+
/** Unbind event listener */
|
|
403
|
+
off(event: string, handler?: AnyFunc): this;
|
|
404
|
+
/** Fire event */
|
|
405
|
+
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
845
406
|
/**
|
|
846
407
|
* Parse href into Location object.
|
|
847
408
|
* Parses query and hash sections of href, returns structured routing information.
|
|
@@ -907,7 +468,7 @@ interface ServiceEvent extends ChangeEvent {
|
|
|
907
468
|
/**
|
|
908
469
|
* Data payload object carrying this request's data.
|
|
909
470
|
*/
|
|
910
|
-
readonly payload:
|
|
471
|
+
readonly payload: PayloadApi;
|
|
911
472
|
/**
|
|
912
473
|
* Error object, present if request throws an error, otherwise null.
|
|
913
474
|
*/
|
|
@@ -924,325 +485,178 @@ interface ViewEvent extends ChangeEvent {
|
|
|
924
485
|
readonly id: string;
|
|
925
486
|
}
|
|
926
487
|
/**
|
|
927
|
-
* Frame static event interface carrying associated Frame
|
|
488
|
+
* Frame static event interface carrying associated Frame object.
|
|
928
489
|
* Carried in Frame's add/remove static events.
|
|
929
490
|
*/
|
|
930
491
|
interface FrameStaticEvent extends ChangeEvent {
|
|
931
492
|
/**
|
|
932
|
-
* Associated Frame
|
|
493
|
+
* Associated Frame object.
|
|
933
494
|
*/
|
|
934
|
-
readonly frame:
|
|
495
|
+
readonly frame: FrameObj;
|
|
935
496
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
497
|
+
/**
|
|
498
|
+
* Functional emitter API.
|
|
499
|
+
*
|
|
500
|
+
* Returned by `createEmitter()`. No `this` binding — handlers are called
|
|
501
|
+
* with `null` context. Methods return the API object for chaining.
|
|
502
|
+
*/
|
|
503
|
+
interface EmitterApi<T = unknown> {
|
|
504
|
+
on(name: string, fn: (e?: ChangeEvent) => void): EmitterApi<T>;
|
|
505
|
+
off(name: string, fn?: AnyFunc): EmitterApi<T>;
|
|
506
|
+
fire(name: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): EmitterApi<T>;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Functional cache API.
|
|
510
|
+
*
|
|
511
|
+
* Returned by `createCache()`.
|
|
512
|
+
*/
|
|
513
|
+
interface CacheApi<T = unknown> {
|
|
514
|
+
set(key: string, resource: T): void;
|
|
515
|
+
get(key: string): T | undefined;
|
|
516
|
+
del(key: string): void;
|
|
517
|
+
has(key: string): boolean;
|
|
518
|
+
clear(): void;
|
|
519
|
+
forEach(callback: (value: T | undefined) => void): void;
|
|
520
|
+
getSize(): number;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Functional updater API.
|
|
524
|
+
*
|
|
525
|
+
* Returned by `createUpdater()`. `refData` is a property.
|
|
526
|
+
* `set()` returns the API object for chaining.
|
|
527
|
+
*/
|
|
528
|
+
interface UpdaterApi {
|
|
529
|
+
get: <T = unknown>(key?: string) => T;
|
|
530
|
+
set: (data: Record<string, unknown>, excludes?: ReadonlySet<string>) => UpdaterApi;
|
|
531
|
+
digest: (data?: Record<string, unknown>, excludes?: ReadonlySet<string>, callback?: () => void) => void;
|
|
532
|
+
forceDigest: () => void;
|
|
533
|
+
snapshot: () => UpdaterApi;
|
|
534
|
+
altered: () => boolean | undefined;
|
|
535
|
+
refData: Record<string, unknown>;
|
|
536
|
+
translate: (data: unknown) => unknown;
|
|
537
|
+
parse: (expr: string) => unknown;
|
|
538
|
+
getChangedKeys: () => ReadonlySet<string>;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Mutable reference cell — used for `signature` and `rendered` on `ViewCtx`.
|
|
542
|
+
* Wraps mutable state in a `Ref<T>` to avoid getter/setter syntax.
|
|
543
|
+
*/
|
|
544
|
+
interface Ref<T> {
|
|
545
|
+
value: T;
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Functional view context.
|
|
549
|
+
*
|
|
550
|
+
* Passed as the first argument to every view setup function. Provides
|
|
551
|
+
* framework APIs without `this` binding.
|
|
552
|
+
*/
|
|
553
|
+
interface ViewCtx {
|
|
554
|
+
/** View ID (same as owner frame ID) */
|
|
941
555
|
id: string;
|
|
942
|
-
/**
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
owner: FrameInterface | number;
|
|
949
|
-
/**
|
|
950
|
-
* Updater instance managing view data binding and DOM rendering.
|
|
951
|
-
*/
|
|
952
|
-
updater: UpdaterInterface;
|
|
953
|
-
/**
|
|
954
|
-
* Signature: > 0 means active, incremented on render, 0 = destroyed */
|
|
955
|
-
signature: number;
|
|
556
|
+
/** Owner frame reference */
|
|
557
|
+
owner: FrameObj;
|
|
558
|
+
/** Updater API for data binding */
|
|
559
|
+
updater: UpdaterApi;
|
|
560
|
+
/** Signature: >0 means active, incremented on render, 0 = destroyed */
|
|
561
|
+
signature: Ref<number>;
|
|
956
562
|
/** Whether rendered at least once */
|
|
957
|
-
rendered
|
|
958
|
-
/**
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
*/
|
|
962
|
-
template?: ViewTemplate | VDomTemplate;
|
|
963
|
-
/**
|
|
964
|
-
* Mixin object array for extending view functionality.
|
|
965
|
-
* Framework merges properties and methods from mixins into view prototype.
|
|
966
|
-
* Event method conflicts are automatically merged into sequential calls.
|
|
967
|
-
*/
|
|
968
|
-
mixins?: Record<string, unknown>[];
|
|
563
|
+
rendered: Ref<boolean>;
|
|
564
|
+
/** View template function (accessed via getTemplate/setTemplate) */
|
|
565
|
+
getTemplate(): ViewTemplate | VDomTemplate | undefined;
|
|
566
|
+
setTemplate(v: ViewTemplate | VDomTemplate | undefined): void;
|
|
969
567
|
/** Location observation config */
|
|
970
568
|
locationObserved: ViewLocationObserved;
|
|
971
|
-
/** Observed state keys */
|
|
972
|
-
|
|
569
|
+
/** Observed state keys (accessed via getObservedStateKeys/setObservedStateKeys) */
|
|
570
|
+
getObservedStateKeys(): string[] | undefined;
|
|
571
|
+
setObservedStateKeys(v: string[] | undefined): void;
|
|
973
572
|
/** Resource map */
|
|
974
573
|
resources: Record<string, ViewResourceEntry>;
|
|
975
|
-
/**
|
|
976
|
-
|
|
977
|
-
/**
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
/** Whether endUpdate has been called (1 = pending) */
|
|
982
|
-
endUpdatePending?: number;
|
|
983
|
-
/** Last rendered VDOM tree (only used when virtualDom is enabled) */
|
|
574
|
+
/** Internal emitter for lifecycle events ("destroy", "render", etc.) */
|
|
575
|
+
emitter: EmitterApi;
|
|
576
|
+
/** EndUpdate pending flag (accessed via getEndUpdatePending/setEndUpdatePending) */
|
|
577
|
+
getEndUpdatePending(): number | undefined;
|
|
578
|
+
setEndUpdatePending(v: number | undefined): void;
|
|
579
|
+
/** Last rendered VDOM tree (only used when vdom is enabled) */
|
|
984
580
|
vdom?: VDomNode;
|
|
985
|
-
/** Render method (wrapped) */
|
|
986
|
-
render(): void;
|
|
987
|
-
/**
|
|
988
|
-
* Init method called after view is mounted.
|
|
989
|
-
* Used for initialization logic.
|
|
990
|
-
* Framework passes two arguments during actual invocation:
|
|
991
|
-
* - initParams: initialization parameter object
|
|
992
|
-
* - options: contains `node: Element` and `deep: boolean`
|
|
993
|
-
*/
|
|
994
|
-
init(): void;
|
|
995
581
|
/** Wrapped render method */
|
|
996
582
|
renderMethod?: AnyFunc;
|
|
997
|
-
/**
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
* @param context `this` binding for callback execution, defaults to view itself
|
|
1019
|
-
*/
|
|
1020
|
-
wrapAsync: <Fn extends AnyFunc>(fn: Fn, context?: unknown) => (...args: Parameters<Fn>) => ReturnType<Fn> | undefined;
|
|
1021
|
-
/**
|
|
1022
|
-
* Listen for URL bar changes, supports two calling modes:
|
|
1023
|
-
* - `observeLocation("page,size", true)` pass parameter keys (comma-separated) and whether to observe path
|
|
1024
|
-
* - `observeLocation({ params: ["page", "size"], path: true })` pass config object
|
|
1025
|
-
* View automatically re-renders when observed parameters or path change.
|
|
1026
|
-
* @param params Parameter keys to observe, supports comma-separated string, string array, or config object
|
|
1027
|
-
* @param observePath Whether to observe path changes
|
|
1028
|
-
*/
|
|
1029
|
-
observeLocation: (params: string | string[] | Record<string, unknown>, observePath?: boolean) => void;
|
|
1030
|
-
/**
|
|
1031
|
-
* Observe data changes for specified keys in State.
|
|
1032
|
-
* View automatically re-renders when observed keys are updated via `State.digest()`.
|
|
1033
|
-
* @param keys Comma-separated key string or string array
|
|
1034
|
-
*/
|
|
1035
|
-
observeState: (keys: string | string[]) => void;
|
|
1036
|
-
/**
|
|
1037
|
-
* Hand over resource to current view for lifecycle management.
|
|
1038
|
-
* Framework automatically calls resource's destroy method at appropriate time when view unmounts or re-renders.
|
|
1039
|
-
* @param key Unique key for managed resource; if key already manages different resource, old resource is auto-destroyed
|
|
1040
|
-
* @param resource Resource object to manage
|
|
1041
|
-
* @param destroyOnRender Whether to auto-destroy resource when render method is called; Service instances typically need auto-destroy on render
|
|
1042
|
-
*/
|
|
1043
|
-
capture: (key: string, resource?: unknown, destroyOnRender?: boolean) => unknown;
|
|
1044
|
-
/**
|
|
1045
|
-
* Release managed resource, returns the resource object regardless of destruction state.
|
|
1046
|
-
* @param key Managed resource key
|
|
1047
|
-
* @param destroy Whether to destroy resource (call its destroy method), defaults to true
|
|
1048
|
-
*/
|
|
1049
|
-
release: (key: string, destroy?: boolean) => unknown;
|
|
1050
|
-
/**
|
|
1051
|
-
* Set leave prompt, e.g., when form has unsaved changes.
|
|
1052
|
-
* Can prompt user to choose between leaving directly or saving before leaving.
|
|
1053
|
-
* Framework calls condition function during route changes (change phase) and page unloads (beforeunload).
|
|
1054
|
-
* Navigation is prevented if condition returns true.
|
|
1055
|
-
* @param message Leave prompt message
|
|
1056
|
-
* @param condition Function to determine whether to show leave prompt; returns true to prevent navigation
|
|
1057
|
-
*/
|
|
1058
|
-
leaveTip: (message: string, condition: () => boolean) => void;
|
|
1059
|
-
/**
|
|
1060
|
-
* Assign method for incremental DOM updates.
|
|
1061
|
-
* Framework uses DOM diff (in-memory real DOM diff) to update only changed portions,
|
|
1062
|
-
* automatically handling child view mounting and unmounting.
|
|
1063
|
-
* Returns true if DOM changed, undefined if no change.
|
|
1064
|
-
* @param options Incremental update config, used internally by framework
|
|
1065
|
-
*/
|
|
1066
|
-
assign?: (options?: unknown) => boolean | undefined;
|
|
1067
|
-
/**
|
|
1068
|
-
* Triggered when view is destroyed.
|
|
1069
|
-
*/
|
|
1070
|
-
onDestroy?: (e?: ChangeEvent) => void;
|
|
1071
|
-
/**
|
|
1072
|
-
* Triggered when render method is called.
|
|
1073
|
-
*/
|
|
1074
|
-
onRender?: (e?: ChangeEvent) => void;
|
|
1075
|
-
/**
|
|
1076
|
-
* Inherit View to create new view subclass.
|
|
1077
|
-
* Supports props.ctor constructor, props.mixins, and event methods (e.g., `'name<click>'`).
|
|
1078
|
-
* @param props Prototype object containing init, render, and other methods
|
|
1079
|
-
* @param statics Object of static methods or properties
|
|
1080
|
-
*/
|
|
1081
|
-
extend?<TProps = object, TStatics = object>(props?: ExtendThisType<TProps & ViewInterface>, statics?: TStatics): ViewInterface & TStatics;
|
|
1082
|
-
/**
|
|
1083
|
-
* Merge multiple mixin objects into View prototype.
|
|
1084
|
-
* Existing properties are not overwritten; event method conflicts are automatically merged into sequential calls.
|
|
1085
|
-
* @param args Mixin object list
|
|
1086
|
-
*/
|
|
1087
|
-
merge?(...args: ExtendThisType<ViewInterface>[]): ViewInterface;
|
|
1088
|
-
navigate?: (path: string, params?: Record<string, unknown>) => void;
|
|
583
|
+
/** Event handlers returned by setup (accessed via getEvents/setEvents) */
|
|
584
|
+
getEvents(): Record<string, AnyFunc> | undefined;
|
|
585
|
+
setEvents(v: Record<string, AnyFunc> | undefined): void;
|
|
586
|
+
/** Cleanup functions registered by useEffect */
|
|
587
|
+
cleanups: Array<() => void>;
|
|
588
|
+
/** assign function returned by setup (accessed via getAssign/setAssign) */
|
|
589
|
+
getAssign(): ((options?: unknown) => boolean | undefined) | undefined;
|
|
590
|
+
setAssign(v: ((options?: unknown) => boolean | undefined) | undefined): void;
|
|
591
|
+
render(): void;
|
|
592
|
+
init(params?: unknown): void;
|
|
593
|
+
beginUpdate(id?: string): void;
|
|
594
|
+
endUpdate(id?: string, inner?: boolean): void;
|
|
595
|
+
wrapAsync<Fn extends AnyFunc>(fn: Fn, context?: unknown): (...args: Parameters<Fn>) => ReturnType<Fn> | undefined;
|
|
596
|
+
observeLocation(params: string | string[] | Record<string, unknown>, observePath?: boolean): void;
|
|
597
|
+
observeState(keys: string | string[]): void;
|
|
598
|
+
capture(key: string, resource?: unknown, destroyOnRender?: boolean): unknown;
|
|
599
|
+
release(key: string, destroy?: boolean): unknown;
|
|
600
|
+
leaveTip(message: string, condition: () => boolean): void;
|
|
601
|
+
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): void;
|
|
602
|
+
on(event: string, handler: AnyFunc): () => void;
|
|
603
|
+
off(event: string, handler?: AnyFunc): void;
|
|
1089
604
|
}
|
|
1090
|
-
type ExtendThisType<T> = Record<string, unknown> & ThisType<T>;
|
|
1091
605
|
/**
|
|
1092
|
-
*
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
606
|
+
* Functional frame object.
|
|
607
|
+
*
|
|
608
|
+
* Created by `createFrame()`. Uses `ViewCtx` for its view reference.
|
|
1095
609
|
*/
|
|
1096
|
-
interface
|
|
1097
|
-
/**
|
|
1098
|
-
* DOM node ID where Frame resides.
|
|
1099
|
-
*/
|
|
610
|
+
interface FrameObj {
|
|
1100
611
|
id: string;
|
|
1101
|
-
/**
|
|
1102
|
-
|
|
1103
|
-
*/
|
|
1104
|
-
readonly viewPath?: string;
|
|
1105
|
-
/**
|
|
1106
|
-
* Parent Frame ID, undefined if this is a top-level Frame.
|
|
1107
|
-
*/
|
|
612
|
+
/** View path (accessed via getViewPath) */
|
|
613
|
+
getViewPath(): string | undefined;
|
|
1108
614
|
readonly parentId: string | undefined;
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
615
|
+
view: ViewCtx | undefined;
|
|
616
|
+
invokeList: FrameInvokeEntry[];
|
|
617
|
+
signature: number;
|
|
618
|
+
destroyed: number;
|
|
619
|
+
hasAltered: number;
|
|
620
|
+
originalTemplate?: string;
|
|
621
|
+
holdFireCreated: number;
|
|
622
|
+
childrenCreated: number;
|
|
623
|
+
childrenAlter: number;
|
|
624
|
+
childrenMap: Record<string, string>;
|
|
625
|
+
childrenCount: number;
|
|
626
|
+
readyCount: number;
|
|
627
|
+
readyMap: Set<string>;
|
|
628
|
+
emitter: EmitterApi;
|
|
629
|
+
/** Dispatcher visit tag (set during dispatcherUpdate walk) */
|
|
630
|
+
dispatcherUpdateTag?: number;
|
|
1115
631
|
mountView(viewPath: string, viewInitParams?: Record<string, unknown>): void;
|
|
1116
|
-
/**
|
|
1117
|
-
* Unmount view from current Frame, triggers view's destroy event and cleans up resources.
|
|
1118
|
-
*/
|
|
1119
632
|
unmountView(): void;
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
*/
|
|
1131
|
-
unmountFrame: (id?: string) => void;
|
|
1132
|
-
/**
|
|
1133
|
-
* Render all child views under specified node (scans v-lark attributes and mounts).
|
|
1134
|
-
* @param zoneId DOM node ID, defaults to current Frame
|
|
1135
|
-
*/
|
|
1136
|
-
mountZone: (zoneId?: string) => void;
|
|
1137
|
-
/**
|
|
1138
|
-
* Unmount all child views under specified node.
|
|
1139
|
-
* @param zoneId DOM node ID, defaults to current Frame
|
|
1140
|
-
*/
|
|
1141
|
-
unmountZone: (zoneId?: string) => void;
|
|
1142
|
-
/**
|
|
1143
|
-
* Get ancestor Frame, defaults to parent Frame (level=1).
|
|
1144
|
-
* @param level Levels to traverse upward, defaults to 1
|
|
1145
|
-
*/
|
|
1146
|
-
parent(level?: number): FrameInterface | undefined;
|
|
1147
|
-
/**
|
|
1148
|
-
* Invoke specified method on view in current Frame.
|
|
1149
|
-
* If view is not rendered yet, invocation is deferred until render completes.
|
|
1150
|
-
* @param name Method name
|
|
1151
|
-
* @param args Arguments array passed to method
|
|
1152
|
-
*/
|
|
1153
|
-
invoke: (name: string, args?: unknown[]) => unknown;
|
|
1154
|
-
/**
|
|
1155
|
-
* Triggered when all descendant views have been created.
|
|
1156
|
-
*/
|
|
1157
|
-
onCreated?: (e?: ChangeEvent) => void;
|
|
1158
|
-
/**
|
|
1159
|
-
* Triggered when descendant views change.
|
|
1160
|
-
*/
|
|
1161
|
-
onAlter?: (e?: ChangeEvent) => void;
|
|
1162
|
-
/**
|
|
1163
|
-
* Get Frame instance by ID, returns undefined if not exists.
|
|
1164
|
-
* @param id Frame's DOM node ID
|
|
1165
|
-
*/
|
|
1166
|
-
get?(id: string): FrameInterface | undefined;
|
|
1167
|
-
/**
|
|
1168
|
-
* Get all Frame instances map for current page.
|
|
1169
|
-
*/
|
|
1170
|
-
getAll?(): Map<string, FrameInterface>;
|
|
1171
|
-
/**
|
|
1172
|
-
* Triggered when Frame is created and registered.
|
|
1173
|
-
*/
|
|
1174
|
-
onAdd?: (e?: FrameStaticEvent) => void;
|
|
1175
|
-
/**
|
|
1176
|
-
* Triggered when Frame is destroyed and unregistered.
|
|
1177
|
-
*/
|
|
1178
|
-
onRemove?: (e?: FrameStaticEvent) => void;
|
|
1179
|
-
view: ViewInterface | undefined;
|
|
1180
|
-
/**
|
|
1181
|
-
* Get ID array of all child Frames for current Frame.
|
|
1182
|
-
* Note: ID positions in array are not fixed.
|
|
1183
|
-
*/
|
|
1184
|
-
children: () => string[];
|
|
1185
|
-
invokeList: FrameInvokeEntry[];
|
|
633
|
+
mountFrame(frameId: string, viewPath: string, viewInitParams?: Record<string, unknown>): FrameObj;
|
|
634
|
+
unmountFrame(id?: string): void;
|
|
635
|
+
mountZone(zoneId?: string): void;
|
|
636
|
+
unmountZone(zoneId?: string): void;
|
|
637
|
+
parent(level?: number): FrameObj | undefined;
|
|
638
|
+
invoke(name: string, args?: unknown[]): unknown;
|
|
639
|
+
children(): string[];
|
|
640
|
+
on(event: string, handler: AnyFunc): FrameObj;
|
|
641
|
+
off(event: string, handler?: AnyFunc): FrameObj;
|
|
642
|
+
fire(event: string, data?: Record<string, unknown>): FrameObj;
|
|
1186
643
|
}
|
|
1187
644
|
/**
|
|
1188
|
-
*
|
|
1189
|
-
*
|
|
1190
|
-
*
|
|
1191
|
-
*
|
|
645
|
+
* View setup function — the functional API for defining views.
|
|
646
|
+
*
|
|
647
|
+
* Called once on mount with a `ViewCtx` and optional init params.
|
|
648
|
+
* Returns a descriptor with `template`, `events`, and optional `assign`.
|
|
1192
649
|
*/
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
*/
|
|
1199
|
-
get: <T = unknown>(key?: string) => T;
|
|
1200
|
-
/**
|
|
1201
|
-
* Set data and track changed keys.
|
|
1202
|
-
* After set, must explicitly call `digest()` to commit changes to page.
|
|
1203
|
-
* Returns this for chaining.
|
|
1204
|
-
* @param data Data object, e.g., `{ a: 1, b: 2 }`
|
|
1205
|
-
* @param excludes Set of keys to exclude from change tracking
|
|
1206
|
-
*/
|
|
1207
|
-
set: (data: Record<string, unknown>, excludes?: ReadonlySet<string>) => UpdaterInterface;
|
|
1208
|
-
/**
|
|
1209
|
-
* Trigger page re-render.
|
|
1210
|
-
* After set, must explicitly call `digest()` to commit changes to page.
|
|
1211
|
-
* Internally executes complete pipeline: template rendering → DOM diff (in-memory real DOM diff) → DOM operations.
|
|
1212
|
-
* @param data Optional data object, if provided calls `set()` first to set data
|
|
1213
|
-
* @param excludes Set of keys to exclude from change tracking
|
|
1214
|
-
* @param callback Callback executed after render completes
|
|
1215
|
-
*/
|
|
1216
|
-
digest: (data?: Record<string, unknown>, excludes?: ReadonlySet<string>, callback?: () => void) => void;
|
|
1217
|
-
/**
|
|
1218
|
-
* Save a snapshot of current data for altered() detection.
|
|
1219
|
-
* Works with `altered()` method to detect whether data has changed.
|
|
1220
|
-
*/
|
|
1221
|
-
snapshot: () => UpdaterInterface;
|
|
1222
|
-
/**
|
|
1223
|
-
* Check if data has changed since last snapshot.
|
|
1224
|
-
* Returns undefined if `snapshot()` has not been called.
|
|
1225
|
-
*/
|
|
1226
|
-
altered: () => boolean | undefined;
|
|
1227
|
-
/** Ref data for template rendering */
|
|
1228
|
-
refData: Record<string, unknown>;
|
|
1229
|
-
/**
|
|
1230
|
-
* Translate raw reference data starting with @ symbol in template.
|
|
1231
|
-
* Replaces `{{@refData}}` with actual value from refData.
|
|
1232
|
-
* @param data Reference data to translate
|
|
1233
|
-
*/
|
|
1234
|
-
translate(data: unknown): unknown;
|
|
1235
|
-
/**
|
|
1236
|
-
* Parse expression string.
|
|
1237
|
-
* @param expr Expression string to parse
|
|
1238
|
-
*/
|
|
1239
|
-
parse(expr: string): unknown;
|
|
1240
|
-
}
|
|
650
|
+
type ViewSetup = (ctx: ViewCtx, params?: unknown) => {
|
|
651
|
+
template?: ViewTemplate | VDomTemplate;
|
|
652
|
+
events?: Record<string, AnyFunc>;
|
|
653
|
+
assign?: (options?: unknown) => boolean | undefined;
|
|
654
|
+
};
|
|
1241
655
|
/**
|
|
1242
656
|
* Data payload interface wrapping API request response data, providing read/write methods.
|
|
1243
657
|
* Payload instances are created internally by Service, developers access via all/one/save callbacks.
|
|
1244
658
|
*/
|
|
1245
|
-
interface
|
|
659
|
+
interface PayloadApi {
|
|
1246
660
|
/**
|
|
1247
661
|
* Get data from Payload by key.
|
|
1248
662
|
* @param key Data key name
|
|
@@ -1257,7 +671,7 @@ interface PayloadInterface {
|
|
|
1257
671
|
* @param keyOrData Key/value string, data object, or endpoint metadata object
|
|
1258
672
|
* @param value Value when first parameter is a key
|
|
1259
673
|
*/
|
|
1260
|
-
set(keyOrData: string | Record<string, unknown> | ServiceMetaEntry, value?: unknown):
|
|
674
|
+
set(keyOrData: string | Record<string, unknown> | ServiceMetaEntry, value?: unknown): PayloadApi;
|
|
1261
675
|
data: Record<string, unknown>;
|
|
1262
676
|
cacheInfo?: ServiceCacheInfo;
|
|
1263
677
|
}
|
|
@@ -1274,43 +688,22 @@ interface ChangeEvent {
|
|
|
1274
688
|
*/
|
|
1275
689
|
readonly keys?: ReadonlySet<string>;
|
|
1276
690
|
}
|
|
1277
|
-
/**
|
|
1278
|
-
* Event emitter interface providing on/off/fire methods for publish-subscribe pattern.
|
|
1279
|
-
*/
|
|
1280
|
-
interface EventEmitterInterface<T = unknown> {
|
|
1281
|
-
/**
|
|
1282
|
-
* Bind event listener, calls handler when event is triggered.
|
|
1283
|
-
* @param name Event name
|
|
1284
|
-
* @param fn Event handler function
|
|
1285
|
-
*/
|
|
1286
|
-
on(name: string, fn: (this: T, e?: ChangeEvent) => void): EventEmitterInterface<T>;
|
|
1287
|
-
/**
|
|
1288
|
-
* Unbind event listener, removes all handlers for event if no handler function is provided.
|
|
1289
|
-
* @param name Event name
|
|
1290
|
-
* @param fn Optional event handler function, if omitted removes all handlers
|
|
1291
|
-
*/
|
|
1292
|
-
off(name: string, fn?: AnyFunc): EventEmitterInterface<T>;
|
|
1293
|
-
/**
|
|
1294
|
-
* Fire event, executes all bound handlers, automatically adds type property to event data.
|
|
1295
|
-
* Supports removing all handlers after firing.
|
|
1296
|
-
* Supports executing handler list in reverse order.
|
|
1297
|
-
* @param name Event name
|
|
1298
|
-
* @param data Event data object
|
|
1299
|
-
* @param remove Whether to remove all handlers after firing
|
|
1300
|
-
* @param lastToFirst Whether to execute handler list in reverse order
|
|
1301
|
-
*/
|
|
1302
|
-
fire(name: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): EventEmitterInterface<T>;
|
|
1303
|
-
}
|
|
1304
691
|
/**
|
|
1305
692
|
* Global state interface providing cross-view data sharing and data change notification capabilities.
|
|
1306
693
|
* State is a singleton object managing app-level state data via get/set/digest.
|
|
1307
|
-
* Supports `clean()` method
|
|
694
|
+
* Supports `clean()` method for automatic cleanup on view destruction.
|
|
1308
695
|
*
|
|
1309
696
|
* Use State for SIMPLE cross-view data (lightweight shared values: counters,
|
|
1310
697
|
* toggles, page title, session info, etc.). For COMPLEX reactive state —
|
|
1311
|
-
* handlers, derived data, or fine-grained subscriptions — use `
|
|
698
|
+
* handlers, derived data, or fine-grained subscriptions — use `createStore` instead.
|
|
1312
699
|
*/
|
|
1313
|
-
interface
|
|
700
|
+
interface StateApi {
|
|
701
|
+
/** Bind event listener */
|
|
702
|
+
on(event: string, handler: (e?: ChangeEvent) => void): this;
|
|
703
|
+
/** Unbind event listener */
|
|
704
|
+
off(event: string, handler?: AnyFunc): this;
|
|
705
|
+
/** Fire event */
|
|
706
|
+
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
1314
707
|
/**
|
|
1315
708
|
* Get data from global state, returns complete state object if key is omitted.
|
|
1316
709
|
* @param key Data key name, omitted returns complete state object
|
|
@@ -1324,16 +717,14 @@ interface StateInterface extends EventEmitterInterface<StateInterface> {
|
|
|
1324
717
|
*/
|
|
1325
718
|
set(data: Record<string, unknown>, excludes?: ReadonlySet<string>): this;
|
|
1326
719
|
/**
|
|
1327
|
-
*
|
|
1328
|
-
*
|
|
1329
|
-
* Keys registered via this method are automatically cleaned when view is destroyed,
|
|
1330
|
-
* and corresponding key reference counts are decremented; data is auto-deleted when count reaches zero.
|
|
720
|
+
* Create a cleanup function for state keys on view destroy.
|
|
721
|
+
* Call inside setup: `State.clean("keys")(ctx)`
|
|
1331
722
|
* @param keys Comma-separated key string
|
|
1332
|
-
* @returns
|
|
723
|
+
* @returns Function that registers destroy cleanup on a ctx
|
|
1333
724
|
*/
|
|
1334
|
-
clean(keys: string): {
|
|
1335
|
-
|
|
1336
|
-
};
|
|
725
|
+
clean(keys: string): (ctx: {
|
|
726
|
+
on: (event: string, handler: () => void) => void;
|
|
727
|
+
}) => void;
|
|
1337
728
|
/**
|
|
1338
729
|
* Detect data changes and dispatch changed event.
|
|
1339
730
|
* After set, must explicitly call `digest()` to dispatch changed event and notify views to update.
|
|
@@ -1384,20 +775,18 @@ interface ServiceMetaEntry {
|
|
|
1384
775
|
*/
|
|
1385
776
|
cache?: number;
|
|
1386
777
|
/**
|
|
1387
|
-
* Before-fetch hook
|
|
778
|
+
* Before-fetch hook.
|
|
1388
779
|
* Hook function called before request is sent, can process request data.
|
|
1389
|
-
* `this` points to current Payload instance.
|
|
1390
780
|
* @param payload Data carrier for current request
|
|
1391
781
|
*/
|
|
1392
|
-
before?: (
|
|
782
|
+
before?: (payload: PayloadApi) => void;
|
|
1393
783
|
/**
|
|
1394
784
|
* After-fetch hook.
|
|
1395
785
|
* Hook function called after request succeeds, before data is passed to view.
|
|
1396
786
|
* Can process response data in this method.
|
|
1397
|
-
* `this` points to current Payload instance.
|
|
1398
787
|
* @param payload Data carrier for current request
|
|
1399
788
|
*/
|
|
1400
|
-
after?: (
|
|
789
|
+
after?: (payload: PayloadApi) => void;
|
|
1401
790
|
/** Clean keys on destroy,
|
|
1402
791
|
* Comma-separated endpoint name string for clearing other endpoints' cache.
|
|
1403
792
|
* For example, if an endpoint creates new data,
|
|
@@ -1406,7 +795,7 @@ interface ServiceMetaEntry {
|
|
|
1406
795
|
*/
|
|
1407
796
|
cleanKeys?: string;
|
|
1408
797
|
/** Additional properties */
|
|
1409
|
-
[
|
|
798
|
+
[k: string]: unknown;
|
|
1410
799
|
}
|
|
1411
800
|
/** Cache info attached to Payload entity */
|
|
1412
801
|
interface ServiceCacheInfo {
|
|
@@ -1421,7 +810,7 @@ interface ServiceCacheInfo {
|
|
|
1421
810
|
/** Timestamp when cached */
|
|
1422
811
|
time: number;
|
|
1423
812
|
}
|
|
1424
|
-
interface
|
|
813
|
+
interface FrameworkApi {
|
|
1425
814
|
/**
|
|
1426
815
|
* Read framework configuration.
|
|
1427
816
|
* - Without arguments: returns the complete config object.
|
|
@@ -1443,49 +832,26 @@ interface FrameworkInterface {
|
|
|
1443
832
|
* @param cfg Config object
|
|
1444
833
|
*/
|
|
1445
834
|
boot(cfg: FrameworkConfig): void;
|
|
1446
|
-
/**
|
|
1447
|
-
* Convert array to hash map object.
|
|
1448
|
-
* - Simple array: `Framework.toMap([1,2,3])` => `{1:1, 2:1, 3:1}`
|
|
1449
|
-
* - Object array: `Framework.toMap([{id:20},{id:30}], 'id')` => `{20:{id:20}, 30:{id:30}}`
|
|
1450
|
-
* @param list Source array
|
|
1451
|
-
* @param key Use object's key value from array as map key
|
|
1452
|
-
*/
|
|
1453
|
-
toMap<T>(list: T[] | null | undefined, key?: keyof T): Record<string, T | number>;
|
|
1454
|
-
/**
|
|
1455
|
-
* Execute methods in try-catch manner, catches exceptions.
|
|
1456
|
-
* Returns return value of last successfully executed method.
|
|
1457
|
-
* @param fns Function or function array
|
|
1458
|
-
* @param args Arguments array passed to functions
|
|
1459
|
-
* @param context `this` binding during function execution
|
|
1460
|
-
* @param configError Optional error callback, receives the caught exception
|
|
1461
|
-
*/
|
|
1462
|
-
toTry(fns: AnyFunc | AnyFunc[], args?: unknown[], context?: unknown, configError?: (e: unknown) => void): unknown;
|
|
1463
835
|
/**
|
|
1464
836
|
* Convert path and params to URL string.
|
|
1465
|
-
* Example: `Framework.
|
|
837
|
+
* Example: `Framework.toUri('/xxx/', {a:'b',c:'d'})` => `/xxx/?a=b&c=d`
|
|
1466
838
|
* @param path Path string
|
|
1467
839
|
* @param params Params object
|
|
1468
840
|
* @param keepEmpty Set of keys whose empty values should be preserved
|
|
1469
841
|
*/
|
|
1470
|
-
|
|
842
|
+
toUri(path: string, params?: Record<string, unknown>, keepEmpty?: Set<string>): string;
|
|
1471
843
|
/**
|
|
1472
844
|
* Parse URL string to path and params object.
|
|
1473
|
-
* Example: `Framework.
|
|
845
|
+
* Example: `Framework.parseUri('/xxx/?a=b&c=d')` => `{path:'/xxx/', params:{a:'b',c:'d'}}`
|
|
1474
846
|
* @param url URL string
|
|
1475
847
|
*/
|
|
1476
|
-
|
|
848
|
+
parseUri(url: string): ParsedUri;
|
|
1477
849
|
/**
|
|
1478
850
|
* Merge source object properties into target object.
|
|
1479
851
|
* @param target Target object
|
|
1480
852
|
* @param sources One or more source objects
|
|
1481
853
|
*/
|
|
1482
|
-
|
|
1483
|
-
/**
|
|
1484
|
-
* Check if object has specified own property (safe hasOwnProperty).
|
|
1485
|
-
* @param owner Object to check, supports undefined/null
|
|
1486
|
-
* @param prop Property key name
|
|
1487
|
-
*/
|
|
1488
|
-
has<T extends object>(owner: T | undefined | null, prop: PropertyKey): boolean;
|
|
854
|
+
assign<T extends object>(target: T, ...sources: Record<string, unknown>[]): T;
|
|
1489
855
|
/**
|
|
1490
856
|
* Get enumerable property keys of object as array.
|
|
1491
857
|
* @param src Source object
|
|
@@ -1497,39 +863,24 @@ interface FrameworkInterface {
|
|
|
1497
863
|
* @param node Node or node ID
|
|
1498
864
|
* @param container Container node or node ID
|
|
1499
865
|
*/
|
|
1500
|
-
|
|
1501
|
-
/**
|
|
1502
|
-
* Shorthand for document.getElementById.
|
|
1503
|
-
* Returns directly if Element is passed.
|
|
1504
|
-
* @param id Node ID or Element object
|
|
1505
|
-
*/
|
|
1506
|
-
node(id: string | Element | null): Element | null;
|
|
866
|
+
nodeInside(node: HTMLElement | string, container: HTMLElement | string): boolean;
|
|
1507
867
|
/**
|
|
1508
868
|
* Ensure DOM element has an ID, auto-generates one if missing.
|
|
1509
869
|
* Returns element's ID.
|
|
1510
870
|
* @param node DOM element object
|
|
1511
871
|
*/
|
|
1512
|
-
|
|
872
|
+
ensureNodeId(node: HTMLElement): string;
|
|
1513
873
|
/**
|
|
1514
874
|
* Load modules using configured module loader.
|
|
1515
875
|
* @param names Module names, supports string or string array
|
|
1516
876
|
* @param callback Callback after modules are loaded
|
|
1517
877
|
*/
|
|
1518
878
|
use(names: string | string[], callback?: (...modules: unknown[]) => void): void;
|
|
1519
|
-
/**
|
|
1520
|
-
* Dynamically inject CSS styles into page. Returns cleanup function to remove injected styles.
|
|
1521
|
-
* Supports single and batch injection.
|
|
1522
|
-
* - `Framework.applyStyle("my-style", "body { color: red; }")` single injection
|
|
1523
|
-
* - `Framework.applyStyle(["style1", "css1", "style2", "css2"])` batch injection
|
|
1524
|
-
* @param styleIdOrPairs Style unique key or [id1, css1, id2, css2, ...] batch array
|
|
1525
|
-
* @param cssText CSS style string (only used when first param is string)
|
|
1526
|
-
*/
|
|
1527
|
-
applyStyle(styleIdOrPairs: string | string[], cssText?: string): () => void;
|
|
1528
879
|
/**
|
|
1529
880
|
* Generate globally unique identifier (GUID).
|
|
1530
881
|
* @param prefix GUID prefix, defaults to "lark-"
|
|
1531
882
|
*/
|
|
1532
|
-
|
|
883
|
+
generateId(prefix?: string): string;
|
|
1533
884
|
/**
|
|
1534
885
|
* Create async callback validity marker.
|
|
1535
886
|
* Returns a check function; if host object is unmarked (e.g., view re-rendered), check function returns false, preventing expired async callbacks from executing.
|
|
@@ -1559,7 +910,7 @@ interface FrameworkInterface {
|
|
|
1559
910
|
* @param eventType Event type string
|
|
1560
911
|
* @param eventInit CustomEvent init options
|
|
1561
912
|
*/
|
|
1562
|
-
|
|
913
|
+
dispatchEvent(target: EventTarget, eventType: string, eventInit?: CustomEventInit): void;
|
|
1563
914
|
/**
|
|
1564
915
|
* Execute a function in try-catch with chunked scheduling.
|
|
1565
916
|
* @param fn Function to execute
|
|
@@ -1579,31 +930,31 @@ interface FrameworkInterface {
|
|
|
1579
930
|
/** Wait result: timeout or view not found */
|
|
1580
931
|
WAIT_TIMEOUT_OR_NOT_FOUND: number;
|
|
1581
932
|
/**
|
|
1582
|
-
*
|
|
1583
|
-
*
|
|
933
|
+
* Emitter factory function.
|
|
934
|
+
* Use `createEmitter()` to create emitter instances.
|
|
1584
935
|
*/
|
|
1585
|
-
|
|
936
|
+
createEmitter: typeof createEmitter;
|
|
1586
937
|
/**
|
|
1587
|
-
* View
|
|
1588
|
-
* Use `
|
|
938
|
+
* View factory function.
|
|
939
|
+
* Use `defineView()` to create view setups.
|
|
1589
940
|
*/
|
|
1590
|
-
|
|
941
|
+
defineView: typeof defineView;
|
|
1591
942
|
/**
|
|
1592
|
-
* Cache
|
|
1593
|
-
* Use `
|
|
943
|
+
* Cache factory function.
|
|
944
|
+
* Use `createCache()` to create cache instances.
|
|
1594
945
|
*/
|
|
1595
|
-
|
|
946
|
+
createCache: typeof createCache;
|
|
1596
947
|
/**
|
|
1597
948
|
* Global state object.
|
|
1598
949
|
*/
|
|
1599
|
-
State:
|
|
950
|
+
State: StateApi;
|
|
1600
951
|
/**
|
|
1601
952
|
* Router object.
|
|
1602
953
|
*/
|
|
1603
|
-
Router:
|
|
954
|
+
Router: RouterApi;
|
|
1604
955
|
/**
|
|
1605
|
-
* Frame
|
|
1606
|
-
* Frame tree for view lifecycle management.
|
|
956
|
+
* Frame singleton.
|
|
957
|
+
* Frame tree for view lifecycle management. Use createFrame() to create frames.
|
|
1607
958
|
*/
|
|
1608
959
|
Frame: typeof Frame;
|
|
1609
960
|
}
|
|
@@ -1687,19 +1038,25 @@ interface FrameworkConfig {
|
|
|
1687
1038
|
/**
|
|
1688
1039
|
* Cross-site (micro-frontend) configuration list.
|
|
1689
1040
|
* Defines remote projects that can be loaded via Module Federation.
|
|
1690
|
-
* Also accessible via `window.
|
|
1041
|
+
* Also accessible via `window.crossSites` for build-time injection.
|
|
1691
1042
|
*/
|
|
1692
|
-
|
|
1043
|
+
crossSites?: CrossSiteConfig[];
|
|
1693
1044
|
/** Default false. */
|
|
1694
|
-
|
|
1695
|
-
/**
|
|
1696
|
-
|
|
1045
|
+
vdom?: boolean;
|
|
1046
|
+
/**
|
|
1047
|
+
* Enable Frame Devtool Bridge (default: true).
|
|
1048
|
+
* When true, installs a postMessage listener so the Lark DevTool browser
|
|
1049
|
+
* extension can inspect the frame tree. Set to false to suppress the bridge
|
|
1050
|
+
* (and any extension-related errors) in environments where the extension
|
|
1051
|
+
* is not available or causes issues.
|
|
1052
|
+
*/
|
|
1053
|
+
devtool?: boolean;
|
|
1697
1054
|
}
|
|
1698
1055
|
interface RouteViewConfig {
|
|
1699
1056
|
/** View path */
|
|
1700
1057
|
view: string;
|
|
1701
1058
|
/** Additional properties merged into location */
|
|
1702
|
-
[
|
|
1059
|
+
[k: string]: unknown;
|
|
1703
1060
|
}
|
|
1704
1061
|
/**
|
|
1705
1062
|
* Configuration for a remote (cross-site) project in the micro-frontend setup.
|
|
@@ -1729,8 +1086,8 @@ interface DomElement extends Element {
|
|
|
1729
1086
|
}
|
|
1730
1087
|
/** Element with frame binding */
|
|
1731
1088
|
interface FrameBoundElement extends HTMLElement {
|
|
1732
|
-
/** Frame
|
|
1733
|
-
frame?:
|
|
1089
|
+
/** Frame object bound to this element */
|
|
1090
|
+
frame?: FrameObj;
|
|
1734
1091
|
/** Whether frame is bound (1 = bound) */
|
|
1735
1092
|
frameBound?: number;
|
|
1736
1093
|
/** View rendered flag */
|
|
@@ -1749,85 +1106,41 @@ interface CompileOptions {
|
|
|
1749
1106
|
/** File path for debug error messages (default: undefined) */
|
|
1750
1107
|
file?: string;
|
|
1751
1108
|
/** Generate VDOM output instead of HTML string (default: false) */
|
|
1752
|
-
|
|
1109
|
+
vdom?: boolean;
|
|
1753
1110
|
}
|
|
1754
1111
|
|
|
1755
1112
|
/**
|
|
1756
|
-
*
|
|
1757
|
-
*
|
|
1113
|
+
* Create an LFU-style bounded cache.
|
|
1114
|
+
*
|
|
1115
|
+
* @param options - Cache configuration
|
|
1116
|
+
* @returns A cache API object with `get`, `set`, `del`, `has`, `clear`, `forEach`, `size`.
|
|
1758
1117
|
*
|
|
1759
1118
|
* @example
|
|
1760
|
-
* const cache =
|
|
1119
|
+
* const cache = createCache({ maxSize: 20, bufferSize: 5 });
|
|
1761
1120
|
* cache.set('user', { name: 'Alice' });
|
|
1762
1121
|
* const user = cache.get('user');
|
|
1763
1122
|
* cache.has('user'); // true
|
|
1764
1123
|
* cache.del('user');
|
|
1765
1124
|
*/
|
|
1766
|
-
declare
|
|
1767
|
-
/** Cache entries array */
|
|
1768
|
-
private entries;
|
|
1769
|
-
/** Fast lookup: prefixed key -> entry */
|
|
1770
|
-
private lookup;
|
|
1771
|
-
/** Buffer size for eviction */
|
|
1772
|
-
private readonly bufferSize;
|
|
1773
|
-
/** Maximum cache size */
|
|
1774
|
-
private readonly maxSize;
|
|
1775
|
-
/** Total capacity (maxSize + bufferSize) */
|
|
1776
|
-
private readonly capacity;
|
|
1777
|
-
/** Callback when entry is removed */
|
|
1778
|
-
private readonly onRemove?;
|
|
1779
|
-
/** Sort comparator */
|
|
1780
|
-
private readonly comparator;
|
|
1781
|
-
constructor(options?: CacheOptions<T>);
|
|
1782
|
-
/** Prefix a key with SPLITTER for namespace isolation */
|
|
1783
|
-
private prefixKey;
|
|
1784
|
-
/**
|
|
1785
|
-
* Get a cached value by key.
|
|
1786
|
-
* Updates frequency and timestamp for cache sorting.
|
|
1787
|
-
*/
|
|
1788
|
-
get(key: string): T | undefined;
|
|
1789
|
-
/**
|
|
1790
|
-
* Iterate all cached values.
|
|
1791
|
-
*/
|
|
1792
|
-
forEach(callback: (value: T | undefined) => void): void;
|
|
1793
|
-
/**
|
|
1794
|
-
* Set or update a cached value.
|
|
1795
|
-
* If key already exists, updates value and increments frequency.
|
|
1796
|
-
* If cache exceeds capacity, triggers eviction.
|
|
1797
|
-
*/
|
|
1798
|
-
set(key: string, value: T): void;
|
|
1799
|
-
/**
|
|
1800
|
-
* Delete a cached entry. Removes it immediately from both the lookup map
|
|
1801
|
-
* and the entries array so the GC can reclaim the value without waiting
|
|
1802
|
-
* for the next eviction sweep.
|
|
1803
|
-
*/
|
|
1804
|
-
del(key: string): void;
|
|
1805
|
-
/**
|
|
1806
|
-
* Check if a key exists in cache.
|
|
1807
|
-
*/
|
|
1808
|
-
has(key: string): boolean;
|
|
1809
|
-
/** Get current cache size */
|
|
1810
|
-
get size(): number;
|
|
1811
|
-
/** Clear all entries */
|
|
1812
|
-
clear(): void;
|
|
1813
|
-
/**
|
|
1814
|
-
* Evict the `bufferSize` worst entries from the cache.
|
|
1815
|
-
*
|
|
1816
|
-
* Uses single-pass partial selection (O(n·k)) instead of sorting the entire
|
|
1817
|
-
* `entries` array (O(n log n)). For the typical `bufferSize = 5` this is
|
|
1818
|
-
* effectively a linear scan with at most 5 in-bucket comparisons per
|
|
1819
|
-
* iteration — and it avoids mutating the rest of `entries`.
|
|
1820
|
-
*/
|
|
1821
|
-
private evictEntries;
|
|
1822
|
-
}
|
|
1125
|
+
declare function createCache<T = unknown>(options?: CacheOptions<T>): CacheApi<T>;
|
|
1823
1126
|
|
|
1824
1127
|
/** Mark framework as booted (called from Framework.boot) */
|
|
1825
1128
|
declare function markBooted(): void;
|
|
1129
|
+
/**
|
|
1130
|
+
* DEBUG: deduplicate direct-mutation warnings.
|
|
1131
|
+
*
|
|
1132
|
+
* Previously this was delayed by 500ms so multiple writes to the same key
|
|
1133
|
+
* would coalesce — but users complained the warning didn't show up at the
|
|
1134
|
+
* point of the mutation. We now warn synchronously and dedupe by key, so
|
|
1135
|
+
* the first hit shows up immediately at the right place in the stack trace.
|
|
1136
|
+
* `clearNotify(key)` resets the dedup flag once the legitimate
|
|
1137
|
+
* `State.set` + `State.digest` actually runs.
|
|
1138
|
+
*/
|
|
1826
1139
|
/**
|
|
1827
1140
|
* Observable in-memory data object.
|
|
1828
1141
|
* Provides get/set/digest/diff/clean methods for cross-view data sharing.
|
|
1829
1142
|
*/
|
|
1830
|
-
declare const State:
|
|
1143
|
+
declare const State: StateApi;
|
|
1831
1144
|
|
|
1832
1145
|
/**
|
|
1833
1146
|
* Router with two-phase change confirmation (supports history and hash modes).
|
|
@@ -1837,7 +1150,7 @@ declare const State: StateInterface;
|
|
|
1837
1150
|
* const loc = Router.parse();
|
|
1838
1151
|
* const diff = Router.diff();
|
|
1839
1152
|
*/
|
|
1840
|
-
declare const Router:
|
|
1153
|
+
declare const Router: RouterApi;
|
|
1841
1154
|
/** Mark framework as booted (called by Framework.boot) */
|
|
1842
1155
|
declare function markRouterBooted(): void;
|
|
1843
1156
|
/** Get current routing mode */
|
|
@@ -1864,124 +1177,23 @@ declare const config: FrameworkConfig;
|
|
|
1864
1177
|
*/
|
|
1865
1178
|
declare function use(names: string | string[], callback?: (...modules: unknown[]) => void): Promise<unknown[]>;
|
|
1866
1179
|
|
|
1867
|
-
/**
|
|
1868
|
-
* CrossSite: Micro-frontend bridge View for cross-project view loading.
|
|
1869
|
-
*
|
|
1870
|
-
* For Lark + Webpack Module Federation.
|
|
1871
|
-
* Provides skeleton rendering, prepare preloading, assign reuse, and remote view mounting.
|
|
1872
|
-
*
|
|
1873
|
-
* Usage (in host project):
|
|
1874
|
-
* 1. Register CrossSite as the bridge view for cross-site paths:
|
|
1875
|
-
* registerViewClass('cross-site', CrossSite);
|
|
1876
|
-
* 2. Use v-lark="cross-site?view=remote-app/views/home¶m=1" in template
|
|
1877
|
-
* 3. CrossSite loads the remote project's prepare module, then mounts the actual view
|
|
1878
|
-
*/
|
|
1879
|
-
|
|
1880
|
-
/**
|
|
1881
|
-
* Reset the projects map cache (useful when crossConfigs change at runtime).
|
|
1882
|
-
*/
|
|
1883
1180
|
declare function resetProjectsMap(): void;
|
|
1884
1181
|
/**
|
|
1885
|
-
* CrossSite bridge
|
|
1182
|
+
* CrossSite view — bridge for micro-frontend remote views.
|
|
1886
1183
|
*
|
|
1887
|
-
*
|
|
1888
|
-
* 1. CrossSite is mounted as a regular view (registered as "cross-site")
|
|
1889
|
-
* 2. render() shows skeleton template with a child container
|
|
1890
|
-
* 3. updateView() loads the remote project's prepare module
|
|
1891
|
-
* 4. Once loaded, mounts the actual remote view into the child container
|
|
1892
|
-
* 5. On re-assign (same view path), calls assign on the remote view instead of re-mounting
|
|
1184
|
+
* Registered via `registerViewClass("cross-site", CrossSite)`.
|
|
1893
1185
|
*/
|
|
1894
|
-
declare const CrossSite:
|
|
1186
|
+
declare const CrossSite: ViewSetup;
|
|
1895
1187
|
|
|
1896
1188
|
/**
|
|
1897
|
-
* Updater
|
|
1189
|
+
* Create an Updater for per-view data binding.
|
|
1190
|
+
*
|
|
1898
1191
|
* Manages view-local data with change detection and DOM diff triggering.
|
|
1899
1192
|
*
|
|
1193
|
+
* @param viewId - The view (frame) ID this updater belongs to
|
|
1194
|
+
* @returns An updater API object with `get`, `set`, `digest`, `forceDigest`, etc.
|
|
1900
1195
|
*/
|
|
1901
|
-
declare
|
|
1902
|
-
/** View ID (same as owner frame ID) */
|
|
1903
|
-
private viewId;
|
|
1904
|
-
/** Current data object */
|
|
1905
|
-
private data;
|
|
1906
|
-
/** Ref data for template rendering */
|
|
1907
|
-
refData: Record<string, unknown>;
|
|
1908
|
-
/** Changed keys in current digest cycle */
|
|
1909
|
-
private changedKeys;
|
|
1910
|
-
/** Whether data has changed since last digest */
|
|
1911
|
-
private hasChangedFlag;
|
|
1912
|
-
/**
|
|
1913
|
-
* Digesting queue: supports re-digest during digest.
|
|
1914
|
-
* Holds pending callbacks; `null` is used as a sentinel marking the start
|
|
1915
|
-
* of an active digest cycle, so `runDigest` can detect re-entrant calls.
|
|
1916
|
-
*/
|
|
1917
|
-
private digestingQueue;
|
|
1918
|
-
/** Monotonically increasing version, bumped each time data actually changes. */
|
|
1919
|
-
private version;
|
|
1920
|
-
/** Snapshot of `version` taken by `snapshot()`, used by `altered()`. */
|
|
1921
|
-
private snapshotVersion;
|
|
1922
|
-
/** Last rendered VDOM tree (only used when virtualDom is enabled) */
|
|
1923
|
-
private vdom?;
|
|
1924
|
-
constructor(viewId: string);
|
|
1925
|
-
/**
|
|
1926
|
-
* Get data by key.
|
|
1927
|
-
* Returns entire data object if key is omitted.
|
|
1928
|
-
*/
|
|
1929
|
-
get<T = unknown>(key?: string): T;
|
|
1930
|
-
/**
|
|
1931
|
-
* Set data, tracking changed keys.
|
|
1932
|
-
* Returns this for chaining.
|
|
1933
|
-
*/
|
|
1934
|
-
set(data: Record<string, unknown>, excludes?: ReadonlySet<string>): this;
|
|
1935
|
-
/**
|
|
1936
|
-
* Detect changes and trigger DOM re-render.
|
|
1937
|
-
*
|
|
1938
|
-
* The core rendering pipeline:
|
|
1939
|
-
* 1. Set data if provided
|
|
1940
|
-
* 2. If changed, run DOM diff (template → new DOM → diff against old DOM)
|
|
1941
|
-
* 3. Apply DOM operations
|
|
1942
|
-
* 4. Apply ID updates
|
|
1943
|
-
* 5. Call endUpdate on views that need re-rendering
|
|
1944
|
-
* 6. Support re-digest during digest via queue
|
|
1945
|
-
*/
|
|
1946
|
-
digest(data?: Record<string, unknown>, excludes?: ReadonlySet<string>, callback?: () => void): void;
|
|
1947
|
-
/**
|
|
1948
|
-
* Core digest execution.
|
|
1949
|
-
*/
|
|
1950
|
-
private runDigest;
|
|
1951
|
-
/**
|
|
1952
|
-
* Save a snapshot of the current data version for `altered()` detection.
|
|
1953
|
-
* Cheap O(1) — records the current monotonic version, no serialization.
|
|
1954
|
-
*/
|
|
1955
|
-
snapshot(): this;
|
|
1956
|
-
/**
|
|
1957
|
-
* Check whether data has changed since the last snapshot.
|
|
1958
|
-
* Returns undefined when no snapshot has been taken yet.
|
|
1959
|
-
*/
|
|
1960
|
-
altered(): boolean | undefined;
|
|
1961
|
-
/**
|
|
1962
|
-
* Translate a refData reference back to its original value.
|
|
1963
|
-
*
|
|
1964
|
-
* The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
|
|
1965
|
-
* emitted by `refFn`. We require that exact shape so a user-supplied
|
|
1966
|
-
* string that merely begins with SPLITTER is never accidentally resolved
|
|
1967
|
-
* (or mishandled as a "missing ref").
|
|
1968
|
-
*/
|
|
1969
|
-
translate(data: unknown): unknown;
|
|
1970
|
-
/**
|
|
1971
|
-
* Resolve a dotted property path against refData.
|
|
1972
|
-
*
|
|
1973
|
-
* Only safe property-path syntax is supported: `a`, `a.b`, `a.b.c`.
|
|
1974
|
-
* Numeric literals (e.g. `1`, `1.5`) are returned as numbers. Anything else
|
|
1975
|
-
* returns `undefined` — we no longer evaluate arbitrary JavaScript via
|
|
1976
|
-
* `new Function`, so the method is CSP-safe and cannot be used as an
|
|
1977
|
-
* injection vector.
|
|
1978
|
-
*/
|
|
1979
|
-
parse(expr: string): unknown;
|
|
1980
|
-
/**
|
|
1981
|
-
* Get the set of keys changed since the last digest (for external inspection).
|
|
1982
|
-
*/
|
|
1983
|
-
getChangedKeys(): ReadonlySet<string>;
|
|
1984
|
-
}
|
|
1196
|
+
declare function createUpdater(viewId: string): UpdaterApi;
|
|
1985
1197
|
|
|
1986
1198
|
/**
|
|
1987
1199
|
* Create a virtual DOM node.
|
|
@@ -1999,174 +1211,212 @@ declare function vdomCreate(tag: string | number, props?: Record<string, unknown
|
|
|
1999
1211
|
declare function createVDomRef(viewId: string): VDomRef;
|
|
2000
1212
|
|
|
2001
1213
|
/**
|
|
2002
|
-
*
|
|
1214
|
+
* @lark.js/mvc Store
|
|
1215
|
+
*
|
|
1216
|
+
* Zustand-aligned state management for Lark MVC.
|
|
1217
|
+
*
|
|
1218
|
+
* Core API:
|
|
1219
|
+
* - create(name, creator): define a store with (set, get) => initialState
|
|
1220
|
+
* - store.getState(): read current state snapshot
|
|
1221
|
+
* - store.setState(partial | updater): shallow-merge state and notify listeners
|
|
1222
|
+
* - store.subscribe(listener): listen for state changes
|
|
1223
|
+
* - store.destroy(): tear down the store
|
|
1224
|
+
* - computed(deps, fn): derived state that auto-recomputes when deps change
|
|
1225
|
+
* - bindStore(view, store, selector?): Lark View lifecycle binding
|
|
2003
1226
|
*/
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
/** Get a value from payload data */
|
|
2011
|
-
get<T = unknown>(key: string): T;
|
|
2012
|
-
/** Set a value in payload data */
|
|
2013
|
-
set(keyOrData: string | Record<string, unknown> | ServiceMetaEntry, value?: unknown): PayloadInterface;
|
|
1227
|
+
type Listener<T> = (state: T, prevState: T) => void;
|
|
1228
|
+
interface StoreApi<T = object> {
|
|
1229
|
+
getState(): T;
|
|
1230
|
+
setState(partial: Partial<T> | ((prev: T) => Partial<T>)): void;
|
|
1231
|
+
subscribe(listener: Listener<T>): () => void;
|
|
1232
|
+
destroy(): void;
|
|
2014
1233
|
}
|
|
1234
|
+
type StateCreator<T> = (set: (partial: Partial<T> | ((prev: T) => Partial<T>)) => void, get: () => T) => T;
|
|
2015
1235
|
/**
|
|
2016
|
-
*
|
|
2017
|
-
*
|
|
2018
|
-
*
|
|
1236
|
+
* Declare a derived (computed) store property.
|
|
1237
|
+
*
|
|
1238
|
+
* Usage inside a `create` creator:
|
|
1239
|
+
* ```ts
|
|
1240
|
+
* const store = create("counter", (set, get) => ({
|
|
1241
|
+
* count: 0,
|
|
1242
|
+
* doubled: computed(["count"], () => get().count * 2),
|
|
1243
|
+
* }));
|
|
1244
|
+
* ```
|
|
1245
|
+
*
|
|
1246
|
+
* `deps` lists the state keys the computed reads. Whenever any dep changes
|
|
1247
|
+
* via `setState`, the computed re-evaluates before listeners are notified.
|
|
1248
|
+
* Writes to a computed key via `setState` are silently ignored.
|
|
2019
1249
|
*/
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
1250
|
+
declare function computed<T>(deps: readonly string[], fn: () => T): T;
|
|
1251
|
+
declare function createStore<T extends object>(name: string, creator: StateCreator<T>): StoreApi<T>;
|
|
1252
|
+
/**
|
|
1253
|
+
* Bind a store to a Lark View. Subscribes to state changes and auto-unsubscribes
|
|
1254
|
+
* when the view is destroyed.
|
|
1255
|
+
*
|
|
1256
|
+
* @param view - Lark View instance (must have updater.set/digest and on("destroy"))
|
|
1257
|
+
* @param store - Store created via `create()`
|
|
1258
|
+
* @param selector - Optional function to pick a subset of state for the updater.
|
|
1259
|
+
* If omitted, only non-function state keys are forwarded.
|
|
1260
|
+
* @returns unsubscribe function
|
|
1261
|
+
*
|
|
1262
|
+
* @example
|
|
1263
|
+
* ```ts
|
|
1264
|
+
* // Observe all state
|
|
1265
|
+
* bindStore(this, useCountStore);
|
|
1266
|
+
*
|
|
1267
|
+
* // Observe with selector
|
|
1268
|
+
* bindStore(this, useCountStore, (s) => ({ count: s.count }));
|
|
1269
|
+
* ```
|
|
1270
|
+
*/
|
|
1271
|
+
declare function bindStore<T>(view: unknown, store: StoreApi<T>, selector?: (state: T) => Record<string, unknown>): () => void;
|
|
1272
|
+
|
|
1273
|
+
/**
|
|
1274
|
+
* Hooks runtime for the functional view system.
|
|
1275
|
+
*
|
|
1276
|
+
* Hooks (`useState`, `useEffect`, `useStore`, etc.) work via a module-level
|
|
1277
|
+
* `currentCtx` that is set during setup function execution. The setup function
|
|
1278
|
+
* runs once on mount (inside `mountCtx`), and hooks register state, effects,
|
|
1279
|
+
* and subscriptions on the ctx.
|
|
1280
|
+
*
|
|
1281
|
+
* Key difference from React hooks: Lark's setup runs ONCE (not on every
|
|
1282
|
+
* render). `useState` returns a `[getter, setter]` pair where the getter
|
|
1283
|
+
* always reads from `ctx.updater.data` — avoiding stale closures. The
|
|
1284
|
+
* template (compiled from `.html`) reads from `updater.data` independently
|
|
1285
|
+
* of the setup function's closures.
|
|
1286
|
+
*/
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Declare view-local state backed by `ctx.updater.data`.
|
|
1290
|
+
*
|
|
1291
|
+
* Returns a `[getter, setter]` pair. The getter always reads the latest
|
|
1292
|
+
* value from `ctx.updater.data[key]`, avoiding stale closures in event
|
|
1293
|
+
* handlers. The setter writes to `ctx.updater.data` and triggers a digest.
|
|
1294
|
+
*
|
|
1295
|
+
* @param key - The data key in `updater.data`
|
|
1296
|
+
* @param initial - Initial value (set once on first call)
|
|
1297
|
+
*
|
|
1298
|
+
* @example
|
|
1299
|
+
* const [getCount, setCount] = useState('count', 0);
|
|
1300
|
+
* // In event handler:
|
|
1301
|
+
* "incr<click>": (e) => setCount(getCount() + 1)
|
|
1302
|
+
*/
|
|
1303
|
+
declare function useState<T>(key: string, initial: T): [() => T, (v: T) => void];
|
|
1304
|
+
/**
|
|
1305
|
+
* Register a side effect with optional cleanup.
|
|
1306
|
+
*
|
|
1307
|
+
* The effect function runs immediately during setup. If it returns a cleanup
|
|
1308
|
+
* function, that cleanup is called on view destroy (or on HMR re-setup).
|
|
1309
|
+
*
|
|
1310
|
+
* Unlike React's `useEffect`, this runs synchronously during setup (not
|
|
1311
|
+
* deferred to a later tick) and does not re-run on dependency changes
|
|
1312
|
+
* (since setup only runs once).
|
|
1313
|
+
*
|
|
1314
|
+
* @example
|
|
1315
|
+
* useEffect(() => {
|
|
1316
|
+
* const timer = setInterval(tick, 1000);
|
|
1317
|
+
* return () => clearInterval(timer);
|
|
1318
|
+
* });
|
|
1319
|
+
*/
|
|
1320
|
+
declare function useEffect(fn: () => (() => void) | void, _deps?: unknown[]): void;
|
|
2038
1321
|
/**
|
|
2039
|
-
*
|
|
1322
|
+
* Bind a store to the view's updater. The store's state is synced to
|
|
1323
|
+
* `ctx.updater.data` automatically. Auto-unsubscribes on view destroy.
|
|
1324
|
+
*
|
|
1325
|
+
* @param store - The store created by `create()`
|
|
1326
|
+
* @param selector - Optional selector to pick which keys to sync
|
|
1327
|
+
* @returns A getter that reads the selected state from updater.data
|
|
2040
1328
|
*
|
|
2041
|
-
*
|
|
2042
|
-
*
|
|
2043
|
-
*
|
|
2044
|
-
*
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
1329
|
+
* @example
|
|
1330
|
+
* const getCount = useStore(useCountStore, (s) => ({ count: s.count }));
|
|
1331
|
+
* // In event handler:
|
|
1332
|
+
* "incr<click>": (e) => useCountStore.getState().increment()
|
|
1333
|
+
*/
|
|
1334
|
+
declare function useStore<T extends Record<string, unknown>>(store: StoreApi<T>, selector?: (s: T) => Partial<T>): () => Partial<T>;
|
|
1335
|
+
/**
|
|
1336
|
+
* Set up an interval that is automatically cleared on view destroy.
|
|
2048
1337
|
*
|
|
2049
|
-
*
|
|
2050
|
-
*
|
|
2051
|
-
*
|
|
2052
|
-
*
|
|
1338
|
+
* @param fn - Function to call on each interval
|
|
1339
|
+
* @param delay - Interval delay in milliseconds
|
|
1340
|
+
*
|
|
1341
|
+
* @example
|
|
1342
|
+
* useInterval(() => {
|
|
1343
|
+
* ctx.updater.set({ time: Date.now() }).digest();
|
|
1344
|
+
* }, 1000);
|
|
1345
|
+
*/
|
|
1346
|
+
declare function useInterval(fn: () => void, delay: number): void;
|
|
1347
|
+
/**
|
|
1348
|
+
* Set up a timeout that is automatically cleared on view destroy.
|
|
1349
|
+
*
|
|
1350
|
+
* @param fn - Function to call after delay
|
|
1351
|
+
* @param delay - Timeout delay in milliseconds
|
|
1352
|
+
*/
|
|
1353
|
+
declare function useTimeout(fn: () => void, delay: number): void;
|
|
1354
|
+
/**
|
|
1355
|
+
* Capture a resource (e.g., a Service instance, observer, etc.) that is
|
|
1356
|
+
* automatically destroyed on view destroy or render (if destroyOnRender).
|
|
1357
|
+
*
|
|
1358
|
+
* @param key - Unique key for the resource
|
|
1359
|
+
* @param resource - The resource object (must have a `destroy()` method)
|
|
1360
|
+
* @param destroyOnRender - If true, destroyed on next render call
|
|
1361
|
+
*
|
|
1362
|
+
* @example
|
|
1363
|
+
* const service = createService(syncFn);
|
|
1364
|
+
* useResource('myService', service.instance(), true);
|
|
1365
|
+
*/
|
|
1366
|
+
declare function useResource(key: string, resource: unknown, destroyOnRender?: boolean): void;
|
|
1367
|
+
/**
|
|
1368
|
+
* Register an event handler on the view's internal emitter.
|
|
1369
|
+
* Automatically unregistered on view destroy.
|
|
1370
|
+
*
|
|
1371
|
+
* @param event - Event name (e.g., "destroy", "render")
|
|
1372
|
+
* @param handler - Event handler function
|
|
1373
|
+
*
|
|
1374
|
+
* @example
|
|
1375
|
+
* useEvent("destroy", () => console.log("View destroyed"));
|
|
1376
|
+
*/
|
|
1377
|
+
declare function useEvent(event: string, handler: AnyFunc): void;
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* Create a Payload wrapping API response data.
|
|
2053
1381
|
*/
|
|
2054
|
-
declare
|
|
2055
|
-
|
|
1382
|
+
declare function createPayload(data?: Record<string, unknown>): PayloadApi;
|
|
1383
|
+
interface ServiceInstance {
|
|
2056
1384
|
id: string;
|
|
2057
|
-
/** Whether service is busy (1 = busy) */
|
|
2058
1385
|
busy: number;
|
|
2059
|
-
/** Whether service is destroyed (1 = destroyed) */
|
|
2060
1386
|
destroyed: number;
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
private _emitter;
|
|
2067
|
-
constructor();
|
|
2068
|
-
/** Instance event emitter (public accessor) */
|
|
2069
|
-
get emitter(): EventEmitterInterface;
|
|
2070
|
-
/**
|
|
2071
|
-
* Get internals object for serviceSend compatibility.
|
|
2072
|
-
* References per-type static state from the current class.
|
|
2073
|
-
*/
|
|
2074
|
-
get internals(): ServiceSendTarget["internals"];
|
|
2075
|
-
/**
|
|
2076
|
-
* Get type reference (the constructor) for serviceSend compatibility.
|
|
2077
|
-
* Static methods like get/create are accessible via the constructor.
|
|
2078
|
-
*/
|
|
2079
|
-
get type(): ServiceSendTarget["type"];
|
|
2080
|
-
/**
|
|
2081
|
-
* Fetch all endpoints, callback when all complete.
|
|
2082
|
-
* Uses cache when available.
|
|
2083
|
-
*/
|
|
2084
|
-
all(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): this;
|
|
2085
|
-
/**
|
|
2086
|
-
* Fetch all endpoints, callback on each completion.
|
|
2087
|
-
*/
|
|
2088
|
-
one(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): this;
|
|
2089
|
-
/**
|
|
2090
|
-
* Fetch all endpoints, skip cache (always request).
|
|
2091
|
-
*/
|
|
2092
|
-
save(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): this;
|
|
2093
|
-
/**
|
|
2094
|
-
* Enqueue a task for sequential execution.
|
|
2095
|
-
*/
|
|
2096
|
-
enqueue(callback: AnyFunc): this;
|
|
2097
|
-
/**
|
|
2098
|
-
* Dequeue and execute the next task in queue.
|
|
2099
|
-
*/
|
|
1387
|
+
emitter: EmitterApi;
|
|
1388
|
+
all(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInstance;
|
|
1389
|
+
one(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInstance;
|
|
1390
|
+
save(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInstance;
|
|
1391
|
+
enqueue(callback: AnyFunc): ServiceInstance;
|
|
2100
1392
|
dequeue(...args: unknown[]): void;
|
|
2101
|
-
/**
|
|
2102
|
-
* Destroy the service instance.
|
|
2103
|
-
* After destruction, no new requests can be sent.
|
|
2104
|
-
*/
|
|
2105
1393
|
destroy(): void;
|
|
2106
|
-
on(event: string, handler: AnyFunc):
|
|
2107
|
-
off(event: string, handler?: AnyFunc):
|
|
2108
|
-
fire(event: string, data?: Record<string, unknown>):
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
static _syncFn: (payload: Payload, callback: () => void) => void;
|
|
2117
|
-
/** Per-type static event emitter */
|
|
2118
|
-
static _staticEmitter: EventEmitter<unknown>;
|
|
2119
|
-
/** Per-type cache max size */
|
|
2120
|
-
static _cacheMax: number;
|
|
2121
|
-
/** Per-type cache buffer size */
|
|
2122
|
-
static _cacheBuffer: number;
|
|
2123
|
-
/**
|
|
2124
|
-
* Register API endpoint metadata.
|
|
2125
|
-
*/
|
|
2126
|
-
static add(attrs: ServiceMetaEntry | ServiceMetaEntry[]): void;
|
|
2127
|
-
/**
|
|
2128
|
-
* Get metadata for an API endpoint.
|
|
2129
|
-
*/
|
|
2130
|
-
static meta(attrs: string | Record<string, unknown>): ServiceMetaEntry;
|
|
2131
|
-
/**
|
|
2132
|
-
* Create a Payload for an API request.
|
|
2133
|
-
*/
|
|
2134
|
-
static create(attrs: Record<string, unknown>): Payload;
|
|
2135
|
-
/**
|
|
2136
|
-
* Get or create a Payload for an API request.
|
|
2137
|
-
*/
|
|
2138
|
-
static get(attrs: Record<string, unknown>, createNew?: boolean): {
|
|
2139
|
-
entity: Payload;
|
|
1394
|
+
on(event: string, handler: AnyFunc): ServiceInstance;
|
|
1395
|
+
off(event: string, handler?: AnyFunc): ServiceInstance;
|
|
1396
|
+
fire(event: string, data?: Record<string, unknown>): ServiceInstance;
|
|
1397
|
+
}
|
|
1398
|
+
interface ServiceApi {
|
|
1399
|
+
add(attrs: ServiceMetaEntry | ServiceMetaEntry[]): void;
|
|
1400
|
+
meta(attrs: string | Record<string, unknown>): ServiceMetaEntry;
|
|
1401
|
+
create(attrs: Record<string, unknown>): PayloadApi;
|
|
1402
|
+
get(attrs: Record<string, unknown>, createNew?: boolean): {
|
|
1403
|
+
entity: PayloadApi;
|
|
2140
1404
|
needsUpdate: boolean;
|
|
2141
1405
|
};
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
*/
|
|
2149
|
-
static clear(names: string | string[]): void;
|
|
2150
|
-
static on(event: string, handler: AnyFunc): void;
|
|
2151
|
-
static off(event: string, handler?: AnyFunc): void;
|
|
2152
|
-
static fire(event: string, data?: Record<string, unknown>): void;
|
|
2153
|
-
/**
|
|
2154
|
-
* Create a new Service subclass with a custom sync function.
|
|
2155
|
-
*
|
|
2156
|
-
* Each subclass gets its OWN copies of every per-type static field
|
|
2157
|
-
* (`_metaList`, `_payloadCache`, `_pendingCacheKeys`, `_syncFn`,
|
|
2158
|
-
* `_staticEmitter`, `_cacheMax`, `_cacheBuffer`) via `static override`.
|
|
2159
|
-
* This is intentional: it ensures that endpoint metadata, cache state,
|
|
2160
|
-
* in-flight dedup keys, and event subscribers are fully isolated between
|
|
2161
|
-
* different Service types, even when one extends another.
|
|
2162
|
-
*
|
|
2163
|
-
* **Do not refactor these `static override` declarations away** — sharing
|
|
2164
|
-
* them through prototype inheritance would let endpoints registered on one
|
|
2165
|
-
* subclass leak into another, and the LFU cache evictions of one type
|
|
2166
|
-
* would race with those of another.
|
|
2167
|
-
*/
|
|
2168
|
-
static extend(this: typeof Service, newSyncFn: (payload: Payload, callback: () => void) => void, newCacheMax?: number, newCacheBuffer?: number): typeof Service;
|
|
1406
|
+
cached(attrs: Record<string, unknown>): PayloadApi | undefined;
|
|
1407
|
+
clear(names: string | string[]): void;
|
|
1408
|
+
on(event: string, handler: AnyFunc): void;
|
|
1409
|
+
off(event: string, handler?: AnyFunc): void;
|
|
1410
|
+
fire(event: string, data?: Record<string, unknown>): void;
|
|
1411
|
+
instance(): ServiceInstance;
|
|
2169
1412
|
}
|
|
1413
|
+
/**
|
|
1414
|
+
* Create a Service type with a custom sync function.
|
|
1415
|
+
*
|
|
1416
|
+
* Each call creates independent closure state (metaList, payloadCache, etc.),
|
|
1417
|
+
* ensuring full isolation between different Service types.
|
|
1418
|
+
*/
|
|
1419
|
+
declare function createService(syncFn: (payload: PayloadApi, callback: () => void) => void, cacheMax?: number, cacheBuffer?: number): ServiceApi;
|
|
2170
1420
|
|
|
2171
1421
|
/**
|
|
2172
1422
|
* DOM event delegation system.
|
|
@@ -2189,7 +1439,7 @@ declare const EventDelegator: {
|
|
|
2189
1439
|
/**
|
|
2190
1440
|
* Set the frame getter function (called by Framework.boot).
|
|
2191
1441
|
*/
|
|
2192
|
-
setFrameGetter(getter: (id: string) =>
|
|
1442
|
+
setFrameGetter(getter: (id: string) => FrameObj | undefined): void;
|
|
2193
1443
|
/**
|
|
2194
1444
|
* Get next element GUID.
|
|
2195
1445
|
*/
|
|
@@ -2200,7 +1450,7 @@ declare const EventDelegator: {
|
|
|
2200
1450
|
* Main framework object.
|
|
2201
1451
|
* Provides boot, config, and all global utility methods.
|
|
2202
1452
|
*/
|
|
2203
|
-
declare const Framework:
|
|
1453
|
+
declare const Framework: FrameworkApi;
|
|
2204
1454
|
|
|
2205
1455
|
/**
|
|
2206
1456
|
* Sync view state with URL query parameters.
|
|
@@ -2215,84 +1465,114 @@ declare const Framework: FrameworkInterface;
|
|
|
2215
1465
|
*
|
|
2216
1466
|
* @example
|
|
2217
1467
|
* ```ts
|
|
2218
|
-
* export default
|
|
2219
|
-
*
|
|
2220
|
-
*
|
|
2221
|
-
*
|
|
2222
|
-
*
|
|
2223
|
-
*
|
|
2224
|
-
*
|
|
2225
|
-
*
|
|
2226
|
-
*
|
|
2227
|
-
*
|
|
2228
|
-
* }
|
|
2229
|
-
* "nextPage<click>"() {
|
|
2230
|
-
* this.setState((prev) => ({ page: String(Number(prev.page) + 1) }));
|
|
2231
|
-
* },
|
|
1468
|
+
* export default defineView((ctx) => {
|
|
1469
|
+
* const [state, setState] = useUrlState(ctx, { page: "1", size: "20" });
|
|
1470
|
+
* ctx.updater.set({ page: state.page, size: state.size }).digest();
|
|
1471
|
+
* return {
|
|
1472
|
+
* template,
|
|
1473
|
+
* events: {
|
|
1474
|
+
* "nextPage<click>"() {
|
|
1475
|
+
* setState((prev) => ({ page: String(Number(prev.page) + 1) }));
|
|
1476
|
+
* },
|
|
1477
|
+
* },
|
|
1478
|
+
* };
|
|
2232
1479
|
* });
|
|
2233
1480
|
* ```
|
|
2234
1481
|
*/
|
|
2235
|
-
declare function useUrlState<S extends Record<string, string>>(view:
|
|
1482
|
+
declare function useUrlState<S extends Record<string, string>>(view: ViewCtx, initialState?: S): [Readonly<S>, (patch: Partial<S> | ((prev: S) => Partial<S>)) => void];
|
|
1483
|
+
|
|
1484
|
+
interface HotContext {
|
|
1485
|
+
accept(cb?: (mod: {
|
|
1486
|
+
default?: unknown;
|
|
1487
|
+
} | undefined) => void): void;
|
|
1488
|
+
dispose(cb: (data: unknown) => void): void;
|
|
1489
|
+
invalidate(): void;
|
|
1490
|
+
}
|
|
1491
|
+
declare function reloadViews(viewPath: string): void;
|
|
1492
|
+
declare function hotSwapView(frame: FrameObj, newSetup: ViewSetup): void;
|
|
1493
|
+
declare function hotSwapFrames(viewPath: string, newSetup: ViewSetup): void;
|
|
1494
|
+
declare function hotSwapByTemplate(oldTemplate: ViewTemplate, newTemplate: ViewTemplate): void;
|
|
1495
|
+
declare function hotSwapByView(oldSetup: ViewSetup, newSetup: ViewSetup): void;
|
|
2236
1496
|
|
|
2237
1497
|
/**
|
|
2238
|
-
*
|
|
1498
|
+
* HMR injection code generator — shared across Vite, Webpack, and Rspack.
|
|
2239
1499
|
*
|
|
2240
|
-
*
|
|
1500
|
+
* ## Why this file exists
|
|
2241
1501
|
*
|
|
2242
|
-
*
|
|
2243
|
-
*
|
|
2244
|
-
*
|
|
2245
|
-
*
|
|
2246
|
-
*
|
|
2247
|
-
*
|
|
2248
|
-
*
|
|
2249
|
-
*
|
|
1502
|
+
* React's `@vitejs/plugin-react` and Vue's `@vitejs/plugin-vue` auto-inject
|
|
1503
|
+
* HMR boilerplate at compile time so users never write `import.meta.hot`
|
|
1504
|
+
* themselves. Lark's `larkMvcPlugin` / `larkMvcLoader` previously did NOT
|
|
1505
|
+
* inject any HMR code, forcing users to manually call `acceptView()` /
|
|
1506
|
+
* `disposeView()` in every view file — a poor DX.
|
|
1507
|
+
*
|
|
1508
|
+
* This module generates the HMR snippet strings that the three bundler
|
|
1509
|
+
* integrations (vite.ts, webpack.ts, rspack.ts) append to compiled output.
|
|
1510
|
+
* Extracting the logic here keeps the three plugin files DRY and makes the
|
|
1511
|
+
* cross-bundler differences (Vite's `import.meta.hot` vs Webpack/Rspack's
|
|
1512
|
+
* `module.hot`) explicit and testable.
|
|
1513
|
+
*
|
|
1514
|
+
* ## Two injection targets
|
|
1515
|
+
*
|
|
1516
|
+
* 1. **Template module** (compiled from `.html`): self-accepts. When the
|
|
1517
|
+
* `.html` changes, the accept callback calls `hotSwapByTemplate(old, new)`
|
|
1518
|
+
* to update the template on all mounted views — preserving state.
|
|
1519
|
+
*
|
|
1520
|
+
* 2. **View class module** (`.ts` file that imports `.html`): self-accepts.
|
|
1521
|
+
* When the `.ts` changes, the accept callback calls
|
|
1522
|
+
* `hotSwapByView(old, new)` to swap the setup function on all mounted
|
|
1523
|
+
* instances — preserving state.
|
|
1524
|
+
*
|
|
1525
|
+
* ## Cross-bundler HMR API differences
|
|
1526
|
+
*
|
|
1527
|
+
* | Bundler | HMR context | accept cb receives new module? |
|
|
1528
|
+
* |----------------|------------------------------------------------------|
|
|
1529
|
+
* | Vite | `import.meta.hot` | Yes (`newModule.default`) |
|
|
1530
|
+
* | Webpack (CJS) | `module.hot` | No (module already re-executed)|
|
|
1531
|
+
* | Rspack | `module.hot` | No (module already re-executed)|
|
|
1532
|
+
*
|
|
1533
|
+
* In Vite, the accept callback runs in the OLD module's scope, so local
|
|
1534
|
+
* variables are from the old module. In Webpack/Rspack, the callback runs
|
|
1535
|
+
* in the NEW module's scope (the module has already re-executed), so local
|
|
1536
|
+
* variables are from the new module. The snippets below account for this.
|
|
2250
1537
|
*/
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
getState(): T;
|
|
2254
|
-
setState(partial: Partial<T> | ((prev: T) => Partial<T>)): void;
|
|
2255
|
-
subscribe(listener: Listener<T>): () => void;
|
|
2256
|
-
destroy(): void;
|
|
2257
|
-
}
|
|
2258
|
-
type StateCreator<T> = (set: (partial: Partial<T> | ((prev: T) => Partial<T>)) => void, get: () => T) => T;
|
|
1538
|
+
/** Supported bundler identifiers. */
|
|
1539
|
+
type Bundler = "vite" | "webpack" | "rspack";
|
|
2259
1540
|
/**
|
|
2260
|
-
*
|
|
1541
|
+
* Append HMR code to a compiled template module source.
|
|
2261
1542
|
*
|
|
2262
|
-
*
|
|
2263
|
-
*
|
|
2264
|
-
*
|
|
2265
|
-
* count: 0,
|
|
2266
|
-
* doubled: computed(["count"], () => get().count * 2),
|
|
2267
|
-
* }));
|
|
2268
|
-
* ```
|
|
1543
|
+
* Called by the Vite `load` hook and the Webpack/Rspack loader after
|
|
1544
|
+
* `compileTemplate` returns. The `bundler` parameter selects the correct
|
|
1545
|
+
* HMR API (`import.meta.hot` for Vite, `module.hot` for Webpack/Rspack).
|
|
2269
1546
|
*
|
|
2270
|
-
*
|
|
2271
|
-
*
|
|
2272
|
-
*
|
|
1547
|
+
* @param source - The compiled template module source from `compileTemplate`
|
|
1548
|
+
* @param bundler - Which bundler's HMR API to use
|
|
1549
|
+
* @returns The source with HMR accept/dispose code appended
|
|
2273
1550
|
*/
|
|
2274
|
-
declare function
|
|
2275
|
-
declare function create<T>(name: string, creator: StateCreator<T>): StoreApi<T>;
|
|
1551
|
+
declare function injectTemplateHmrSnippet(source: string, bundler: Bundler): string;
|
|
2276
1552
|
/**
|
|
2277
|
-
*
|
|
2278
|
-
* when the view is destroyed.
|
|
1553
|
+
* Quick check: does this `.ts` source import a `.html` template?
|
|
2279
1554
|
*
|
|
2280
|
-
*
|
|
2281
|
-
*
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
|
|
1555
|
+
* Used by the plugin's `transform` hook to decide whether to inject view
|
|
1556
|
+
* class HMR. Files that don't import `.html` are left untouched.
|
|
1557
|
+
*/
|
|
1558
|
+
declare function importsHtmlTemplate(source: string): boolean;
|
|
1559
|
+
/**
|
|
1560
|
+
* Transform a `.ts` view file source to add view class HMR.
|
|
2285
1561
|
*
|
|
2286
|
-
*
|
|
2287
|
-
*
|
|
2288
|
-
*
|
|
2289
|
-
*
|
|
1562
|
+
* Steps:
|
|
1563
|
+
* 1. Check if the source imports a `.html` template. If not, return as-is.
|
|
1564
|
+
* 2. Find the `export default` declaration (via @babel/parser AST).
|
|
1565
|
+
* 3. Rewrite it to a named const + export, so the HMR snippet can reference
|
|
1566
|
+
* the View class by name (`__larkViewDefault`).
|
|
1567
|
+
* 4. Append the HMR snippet.
|
|
2290
1568
|
*
|
|
2291
|
-
*
|
|
2292
|
-
*
|
|
2293
|
-
*
|
|
1569
|
+
* If the source has no `export default`, or if parsing fails, the source is
|
|
1570
|
+
* returned unchanged (graceful degradation — the file just won't have HMR).
|
|
1571
|
+
*
|
|
1572
|
+
* @param source - The `.ts` source code
|
|
1573
|
+
* @param bundler - Which bundler's HMR API to use
|
|
1574
|
+
* @returns The transformed source with HMR code, or the original if ineligible
|
|
2294
1575
|
*/
|
|
2295
|
-
declare function
|
|
1576
|
+
declare function injectViewHmr(source: string, bundler: Bundler): string;
|
|
2296
1577
|
|
|
2297
|
-
export { CALL_BREAK_TIME,
|
|
2298
|
-
export type { AnyFunc, CacheEntry, CacheInterface, CacheOptions, ChangeEvent, CompileOptions, CrossSiteConfig, DomElement, DomOp, DomRef, EventEmitterInterface, EventListenerEntry, FrameBoundElement, FrameInterface, FrameInvokeEntry, FrameStaticEvent, FrameworkConfig, FrameworkInterface, HotContext, Location, LocationDiff, MixinEventHandler, ParamDiff, ParsedUri, PayloadInterface, PendingCacheEntry, RouteChangeEvent, RouteChangedEvent, RouteViewConfig, RouterInterface, ServiceCacheInfo, ServiceEvent, ServiceMetaEntry, ServiceOptions, StateInterface, StoreApi, UpdaterInterface, VDomCreateFn, VDomNode, VDomRef, VDomTemplate, ViewEvent, ViewEventSelectorEntry, ViewGlobalEventEntry, ViewInterface, ViewLocationObserved, ViewObserveLocation, ViewResourceEntry, ViewTemplate, VoidFunc };
|
|
1578
|
+
export { type AnyFunc, type Bundler, CALL_BREAK_TIME, type CacheApi, type CacheEntry, type CacheOptions, type ChangeEvent, type CompileOptions, CrossSite, type CrossSiteConfig, type DomElement, type DomOp, type DomRef, EVENT_METHOD_REGEXP, type EmitterApi, EventDelegator, type EventListenerEntry, Frame, type FrameApi, type FrameBoundElement, type FrameInvokeEntry, type FrameObj, type FrameStaticEvent, Framework, type FrameworkApi, type FrameworkConfig, type HotContext, LARK_VIEW, type Location, type LocationDiff, type ParamDiff, type ParsedUri, type PayloadApi, type PendingCacheEntry, RouterEvents as ROUTER_EVENTS, type Ref, type RouteChangeEvent, type RouteChangedEvent, type RouteViewConfig, Router, type RouterApi, SPLITTER, type ServiceApi, type ServiceCacheInfo, type ServiceEvent, type ServiceInstance, type ServiceMetaEntry, type ServiceOptions, State, type StateApi, type StoreApi, TAG_NAME_REGEXP, type UpdaterApi, type VDomCreateFn, type VDomNode, type VDomRef, type VDomTemplate, VIEW_EVENT_METHOD_REGEXP, type ViewCtx, type ViewEvent, type ViewLocationObserved, type ViewObserveLocation, type ViewResourceEntry, type ViewSetup, type ViewTemplate, type VoidFunc, bindStore, computed, createCache, createEmitter, createFrame, createPayload, createService, createStore, createUpdater, createVDomRef, defineView, config as frameworkConfig, getRouteMode, hotSwapByTemplate, hotSwapByView, hotSwapFrames, hotSwapView, importsHtmlTemplate, injectTemplateHmrSnippet, injectViewHmr, invalidateViewClass, mark, markBooted, markRouterBooted, nextCounter, registerViewClass, reloadViews, resetProjectsMap, unmark, use, useEffect, useEvent, useInterval, useResource, useState, useStore, useTimeout, useUrlState, vdomCreate };
|