@lark.js/mvc 0.0.4 → 0.0.5
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 +828 -451
- package/dist/{chunk-ANWA22AX.js → chunk-IIIY575B.js} +24 -25
- package/dist/index.cjs +1032 -569
- package/dist/index.d.cts +548 -111
- package/dist/index.d.ts +548 -111
- package/dist/index.js +1023 -567
- package/dist/runtime.cjs +70 -0
- package/dist/runtime.d.cts +29 -0
- package/dist/runtime.d.ts +29 -0
- package/dist/runtime.js +41 -0
- package/dist/vite.cjs +24 -25
- package/dist/vite.d.cts +3 -3
- package/dist/vite.d.ts +3 -3
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +24 -25
- package/dist/webpack.js +1 -1
- package/package.json +21 -8
- package/src/client.d.ts +80 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-cast event emitter class.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* const emitter = new EventEmitter();
|
|
6
|
+
* emitter.on('change', (data) => console.log(data));
|
|
7
|
+
* emitter.fire('change', { key: 'value' });
|
|
8
|
+
*/
|
|
9
|
+
declare class EventEmitter<T = unknown> implements EventEmitterInterface<T> {
|
|
10
|
+
/** Event listeners: prefixed key -> listener array */
|
|
11
|
+
listeners: Map<string, EventListenerEntry[]>;
|
|
12
|
+
/** Number of `fire()` calls currently on the stack (re-entrancy depth). */
|
|
13
|
+
private firingDepth;
|
|
14
|
+
/** Keys whose listener list needs compaction after firing settles. */
|
|
15
|
+
private pendingCompaction;
|
|
16
|
+
/**
|
|
17
|
+
* Bind event listener.
|
|
18
|
+
*/
|
|
19
|
+
on(event: string, handler: (this: T, e: ChangeEvent) => void): this;
|
|
20
|
+
/**
|
|
21
|
+
* Unbind event listener.
|
|
22
|
+
* If handler is provided, removes only that handler.
|
|
23
|
+
* If no handler, removes all handlers for the event.
|
|
24
|
+
*/
|
|
25
|
+
off(event: string, handler?: AnyFunc): this;
|
|
26
|
+
/**
|
|
27
|
+
* Fire event, execute all bound handlers. Safe for re-entrant `off()` calls
|
|
28
|
+
* during dispatch: removed handlers are replaced with noop and compacted
|
|
29
|
+
* after the outermost fire returns.
|
|
30
|
+
*
|
|
31
|
+
* @param event - Event name
|
|
32
|
+
* @param data - Event data (type property added automatically)
|
|
33
|
+
* @param remove - Whether to remove all handlers after firing
|
|
34
|
+
* @param lastToFirst - Whether to execute handlers in reverse order
|
|
35
|
+
*/
|
|
36
|
+
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
37
|
+
}
|
|
38
|
+
|
|
1
39
|
/**
|
|
2
40
|
* Base View class.
|
|
3
41
|
* Views are created via View.extend() and mounted by Frame.
|
|
@@ -14,7 +52,7 @@ declare class View implements ViewInterface {
|
|
|
14
52
|
/** Whether rendered at least once */
|
|
15
53
|
rendered?: boolean;
|
|
16
54
|
/** Whether view has template */
|
|
17
|
-
template?:
|
|
55
|
+
template?: ViewTemplate;
|
|
18
56
|
/** Location observation config */
|
|
19
57
|
locationObserved: ViewLocationObserved;
|
|
20
58
|
/** Observed state keys */
|
|
@@ -27,6 +65,8 @@ declare class View implements ViewInterface {
|
|
|
27
65
|
endUpdatePending?: number;
|
|
28
66
|
/** Internal event storage */
|
|
29
67
|
private _events;
|
|
68
|
+
/** Prototype-stored event maps shape (set by View.prepare). */
|
|
69
|
+
private get protoEventState();
|
|
30
70
|
/**
|
|
31
71
|
* Event bitmask map: eventType -> bitmask (1=root, 2=selector).
|
|
32
72
|
* Read from prototype ($evtObjMap) set by View.prepare.
|
|
@@ -55,6 +95,8 @@ declare class View implements ViewInterface {
|
|
|
55
95
|
on(event: string, handler: AnyFunc): this;
|
|
56
96
|
off(event: string, handler?: AnyFunc): this;
|
|
57
97
|
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
98
|
+
/** Get the owning frame, asserting it has been bound. */
|
|
99
|
+
private get ownerFrame();
|
|
58
100
|
/**
|
|
59
101
|
* Notify view that HTML update is about to begin.
|
|
60
102
|
* Unmounts child frames in the update zone.
|
|
@@ -150,40 +192,44 @@ declare class View implements ViewInterface {
|
|
|
150
192
|
*/
|
|
151
193
|
static merge(this: typeof View, ...mixins: Record<string, unknown>[]): typeof View;
|
|
152
194
|
}
|
|
153
|
-
|
|
154
195
|
/**
|
|
155
|
-
*
|
|
196
|
+
* Type-safe wrapper around `View.extend()`.
|
|
156
197
|
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
198
|
+
* `View.extend({...})` accepts any object literal, and inside its methods
|
|
199
|
+
* `this` is typed only as the base `ViewInterface` — so any custom state
|
|
200
|
+
* field or helper method requires a `(this as MyView).foo` strong-cast at
|
|
201
|
+
* every call site.
|
|
202
|
+
*
|
|
203
|
+
* `defineView()` threads the literal's own shape back into `this` via
|
|
204
|
+
* `ThisType<P & ViewInterface>`, so `this.foo` is typed automatically:
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* const HomeView = defineView({
|
|
208
|
+
* $title: "Home",
|
|
209
|
+
* init() {
|
|
210
|
+
* this.updater.set({ title: this.$title }); // both typed
|
|
211
|
+
* },
|
|
212
|
+
* greet() {
|
|
213
|
+
* return `hello ${this.$title}`;
|
|
214
|
+
* },
|
|
215
|
+
* });
|
|
216
|
+
* ```
|
|
217
|
+
*
|
|
218
|
+
* Runtime semantics are identical to `View.extend(props, statics)` — this is
|
|
219
|
+
* a zero-cost type-only wrapper.
|
|
161
220
|
*/
|
|
162
|
-
declare
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
off(event: string, handler?: AnyFunc): this;
|
|
175
|
-
/**
|
|
176
|
-
* Fire event, execute all bound handlers.
|
|
177
|
-
* Supports executing state management: handlers removed during
|
|
178
|
-
* execution are safely handled.
|
|
179
|
-
*
|
|
180
|
-
* @param event - Event name
|
|
181
|
-
* @param data - Event data (type property added automatically)
|
|
182
|
-
* @param remove - Whether to remove all handlers after firing
|
|
183
|
-
* @param lastToFirst - Whether to execute handlers in reverse order
|
|
184
|
-
*/
|
|
185
|
-
fire(event: string, data?: Record<string, unknown>, remove?: boolean, lastToFirst?: boolean): this;
|
|
186
|
-
}
|
|
221
|
+
declare function defineView<P extends Record<string, unknown>>(props: P & ThisType<P & ViewInterface>, statics?: Record<string, unknown>): typeof View;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Register a View class for a given view path.
|
|
225
|
+
* Called after module loading completes (or up front during boot).
|
|
226
|
+
*/
|
|
227
|
+
declare function registerViewClass(viewPath: string, ViewClass: typeof View): void;
|
|
228
|
+
/**
|
|
229
|
+
* Invalidate a View class from the registry.
|
|
230
|
+
* Used by HMR to force re-loading of a view module.
|
|
231
|
+
*/
|
|
232
|
+
declare function invalidateViewClass(viewPath: string): void;
|
|
187
233
|
|
|
188
234
|
/**
|
|
189
235
|
* Frame (View Frame) class for view lifecycle management.
|
|
@@ -202,8 +248,8 @@ declare class Frame extends EventEmitter implements FrameInterface {
|
|
|
202
248
|
childrenCount: number;
|
|
203
249
|
/** Ready count (children that have fired 'created') */
|
|
204
250
|
readyCount: number;
|
|
205
|
-
/**
|
|
206
|
-
readyMap:
|
|
251
|
+
/** Set of child frame IDs that have fired 'created' */
|
|
252
|
+
readyMap: Set<string>;
|
|
207
253
|
/** View instance */
|
|
208
254
|
viewInstance?: ViewInterface;
|
|
209
255
|
/** Get view instance (read-only) */
|
|
@@ -245,7 +291,7 @@ declare class Frame extends EventEmitter implements FrameInterface {
|
|
|
245
291
|
/**
|
|
246
292
|
* Internal: actually mount the view after class is loaded.
|
|
247
293
|
*/
|
|
248
|
-
doMountView(ViewClass: typeof View, params: Record<string,
|
|
294
|
+
doMountView(ViewClass: typeof View, params: Record<string, unknown>, node: HTMLElement, sign: number): void;
|
|
249
295
|
/**
|
|
250
296
|
* Unmount current view.
|
|
251
297
|
*/
|
|
@@ -279,11 +325,52 @@ declare class Frame extends EventEmitter implements FrameInterface {
|
|
|
279
325
|
* Invoke a method on the view.
|
|
280
326
|
*/
|
|
281
327
|
invoke(name: string, args?: unknown[]): unknown;
|
|
328
|
+
/**
|
|
329
|
+
* Type-safe variant of `invoke`.
|
|
330
|
+
*
|
|
331
|
+
* `invoke()` accepts any string and any args, which silently hides
|
|
332
|
+
* mismatched call sites when a method gets renamed. `invokeTyped` carries
|
|
333
|
+
* the view's method signature through TypeScript so the compiler catches
|
|
334
|
+
* those mistakes:
|
|
335
|
+
*
|
|
336
|
+
* ```ts
|
|
337
|
+
* type Home = View & { loadData(id: string): Promise<void> };
|
|
338
|
+
* frame.invokeTyped<Home, "loadData">("loadData", ["user-1"]);
|
|
339
|
+
* ```
|
|
340
|
+
*
|
|
341
|
+
* Behavior is identical to `invoke` at runtime — same defer / direct-call
|
|
342
|
+
* paths — so it's a drop-in safer overload.
|
|
343
|
+
*/
|
|
344
|
+
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;
|
|
282
345
|
/** Get frame by ID */
|
|
283
346
|
static get(id: string): Frame | undefined;
|
|
284
347
|
/** Get all frames */
|
|
285
348
|
static getAll(): Map<string, Frame>;
|
|
286
|
-
/**
|
|
349
|
+
/**
|
|
350
|
+
* Returns the existing root frame, or `undefined` if none has been created.
|
|
351
|
+
* Pure getter — never creates a Frame, never touches the DOM.
|
|
352
|
+
*
|
|
353
|
+
* Use `Frame.createRoot(id)` to create the root explicitly during framework
|
|
354
|
+
* boot. For Micro-Frontend hosts that own multiple independent containers,
|
|
355
|
+
* use `new Frame(containerId)` directly so each MF mount has its own root.
|
|
356
|
+
*/
|
|
357
|
+
static getRoot(): Frame | undefined;
|
|
358
|
+
/**
|
|
359
|
+
* Create (or return) the singleton root frame for this app.
|
|
360
|
+
*
|
|
361
|
+
* Idempotent: subsequent calls always return the original root regardless
|
|
362
|
+
* of `rootId` — so passing a different id later is silently ignored.
|
|
363
|
+
* `Framework.boot()` is the canonical caller; user code rarely needs this.
|
|
364
|
+
*/
|
|
365
|
+
static createRoot(rootId?: string): Frame;
|
|
366
|
+
/**
|
|
367
|
+
* @deprecated Use `Frame.getRoot()` for read-only access or
|
|
368
|
+
* `Frame.createRoot(id)` to create the root explicitly. The single-method
|
|
369
|
+
* `root()` blurred the distinction and was a common source of bugs in
|
|
370
|
+
* Micro-Frontend hosts.
|
|
371
|
+
*
|
|
372
|
+
* Kept for backward compatibility — behavior unchanged.
|
|
373
|
+
*/
|
|
287
374
|
static root(rootId?: string): Frame;
|
|
288
375
|
/** Bind event listener (static) */
|
|
289
376
|
static on(event: string, handler: AnyFunc): typeof Frame;
|
|
@@ -292,11 +379,6 @@ declare class Frame extends EventEmitter implements FrameInterface {
|
|
|
292
379
|
/** Fire event (static) */
|
|
293
380
|
static fire(event: string, data?: Record<string, unknown>): void;
|
|
294
381
|
}
|
|
295
|
-
/**
|
|
296
|
-
* Register a View class for a given view path.
|
|
297
|
-
* Called after module loading completes.
|
|
298
|
-
*/
|
|
299
|
-
declare function registerViewClass(viewPath: string, ViewClass: typeof View): void;
|
|
300
382
|
|
|
301
383
|
/**
|
|
302
384
|
* Cache class with LFU-style eviction.
|
|
@@ -343,7 +425,9 @@ declare class Cache<T = unknown> implements CacheInterface<T> {
|
|
|
343
425
|
*/
|
|
344
426
|
set(key: string, value: T): void;
|
|
345
427
|
/**
|
|
346
|
-
* Delete a cached entry.
|
|
428
|
+
* Delete a cached entry. Removes it immediately from both the lookup map
|
|
429
|
+
* and the entries array so the GC can reclaim the value without waiting
|
|
430
|
+
* for the next eviction sweep.
|
|
347
431
|
*/
|
|
348
432
|
del(key: string): void;
|
|
349
433
|
/**
|
|
@@ -354,7 +438,14 @@ declare class Cache<T = unknown> implements CacheInterface<T> {
|
|
|
354
438
|
get size(): number;
|
|
355
439
|
/** Clear all entries */
|
|
356
440
|
clear(): void;
|
|
357
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Evict the `bufferSize` worst entries from the cache.
|
|
443
|
+
*
|
|
444
|
+
* Uses single-pass partial selection (O(n·k)) instead of sorting the entire
|
|
445
|
+
* `entries` array (O(n log n)). For the typical `bufferSize = 5` this is
|
|
446
|
+
* effectively a linear scan with at most 5 in-bucket comparisons per
|
|
447
|
+
* iteration — and it avoids mutating the rest of `entries`.
|
|
448
|
+
*/
|
|
358
449
|
private evictEntries;
|
|
359
450
|
}
|
|
360
451
|
|
|
@@ -365,7 +456,9 @@ declare class Cache<T = unknown> implements CacheInterface<T> {
|
|
|
365
456
|
* Lark is a lightweight MVC frontend framework that provides:
|
|
366
457
|
* - View: base view class with extend/merge inheritance and mixin support
|
|
367
458
|
* - Router: hash-based two-phase route confirmation
|
|
368
|
-
* - State: cross-view observable
|
|
459
|
+
* - State: simple cross-view observable singleton (recommended for simple cases)
|
|
460
|
+
* - Store: complex Proxy-based reactive state with observe/handlers/multi-instance
|
|
461
|
+
* (recommended for complex cases)
|
|
369
462
|
* - Service: API request management with caching, queuing, and deduplication
|
|
370
463
|
* - Frame: view frame managing view mount/unmount lifecycle
|
|
371
464
|
* - Updater: view data binding and VDOM diff (in-memory real DOM diff) renderer
|
|
@@ -377,6 +470,8 @@ declare class Cache<T = unknown> implements CacheInterface<T> {
|
|
|
377
470
|
* (TypeScript function parameters are contravariant).
|
|
378
471
|
*/
|
|
379
472
|
type AnyFunc = (...args: any[]) => unknown;
|
|
473
|
+
/** A function that returns void. */
|
|
474
|
+
type VoidFunc = (...args: any[]) => void;
|
|
380
475
|
interface CacheEntry<T> {
|
|
381
476
|
/** Original key without prefix */
|
|
382
477
|
originalKey: string;
|
|
@@ -558,7 +653,13 @@ interface VDomRef {
|
|
|
558
653
|
/** Whether anything changed */
|
|
559
654
|
hasChanged: number;
|
|
560
655
|
}
|
|
561
|
-
|
|
656
|
+
/**
|
|
657
|
+
* Encoded VDOM mutation. The op code matches `Node.appendChild` family at the
|
|
658
|
+
* DOM level — parents are always Elements (you can't appendChild onto text)
|
|
659
|
+
* but the moving / replaced child can be any ChildNode (Element / Text /
|
|
660
|
+
* Comment), so the child slots are typed as ChildNode.
|
|
661
|
+
*/
|
|
662
|
+
type VDomOp = [1, Element, ChildNode] | [2, Element, ChildNode] | [4, Element, ChildNode, ChildNode] | [8, Element, ChildNode, ChildNode];
|
|
562
663
|
interface FrameInvokeEntry {
|
|
563
664
|
/** Method name */
|
|
564
665
|
name: string;
|
|
@@ -583,6 +684,12 @@ interface ViewEventSelectorEntry {
|
|
|
583
684
|
/** Index signature for checking if selector is already registered */
|
|
584
685
|
[selector: string]: unknown;
|
|
585
686
|
}
|
|
687
|
+
/**
|
|
688
|
+
* Compiled template function signature.
|
|
689
|
+
* `data`/`viewId`/`refData` are required; subsequent encoder args are
|
|
690
|
+
* injected by the Updater (encodeHTML/encodeSafe/encodeURIExtra/refFn/encodeQ).
|
|
691
|
+
*/
|
|
692
|
+
type ViewTemplate = (data: unknown, viewId: string, refData: unknown, ...encoders: unknown[]) => string;
|
|
586
693
|
interface ViewLocationObserved {
|
|
587
694
|
/** Whether observing location */
|
|
588
695
|
flag: number;
|
|
@@ -609,6 +716,20 @@ interface ViewGlobalEventEntry {
|
|
|
609
716
|
/** Modifiers */
|
|
610
717
|
modifiers: Record<string, boolean>;
|
|
611
718
|
}
|
|
719
|
+
/**
|
|
720
|
+
* View configuration for listening to URL changes.
|
|
721
|
+
* Used as object parameter for `observeLocation()` method.
|
|
722
|
+
*/
|
|
723
|
+
interface ViewObserveLocation {
|
|
724
|
+
/**
|
|
725
|
+
* Whether to listen for path changes.
|
|
726
|
+
*/
|
|
727
|
+
observePath?: boolean;
|
|
728
|
+
/**
|
|
729
|
+
* Parameter keys to observe, supports comma-separated string or string array.
|
|
730
|
+
*/
|
|
731
|
+
params?: string | string[];
|
|
732
|
+
}
|
|
612
733
|
/**
|
|
613
734
|
* Router interface providing URL parsing, navigation, diff, and event listening capabilities.
|
|
614
735
|
* Supports two-phase route confirmation mechanism: change (can reject) → changed.
|
|
@@ -640,6 +761,23 @@ interface RouterInterface extends EventEmitterInterface<RouterInterface> {
|
|
|
640
761
|
to(pathOrParams: string | Record<string, unknown>, params?: Record<string, unknown>, replace?: boolean, silent?: boolean): void;
|
|
641
762
|
/** Join path segments */
|
|
642
763
|
join(...paths: string[]): string;
|
|
764
|
+
/**
|
|
765
|
+
* Register an async-friendly navigation guard.
|
|
766
|
+
*
|
|
767
|
+
* Each guard is invoked with the parsed `(to, from)` Locations. Guards
|
|
768
|
+
* may return a Promise; the router awaits all guards in registration
|
|
769
|
+
* order. If any guard:
|
|
770
|
+
*
|
|
771
|
+
* - returns / resolves to `false`,
|
|
772
|
+
* - throws or rejects,
|
|
773
|
+
*
|
|
774
|
+
* the navigation is aborted and the URL is reverted. Returning `true`,
|
|
775
|
+
* `undefined`, or any non-false value permits the navigation.
|
|
776
|
+
*
|
|
777
|
+
* Returns an unsubscribe function so the guard can be torn down (e.g.
|
|
778
|
+
* inside a view's `destroy` handler).
|
|
779
|
+
*/
|
|
780
|
+
beforeEach(guard: (to: Location, from: Location) => boolean | void | Promise<boolean | void>): () => void;
|
|
643
781
|
/** Internal: bind hashchange (called by Framework.boot) */
|
|
644
782
|
_bind(): void;
|
|
645
783
|
/** Internal: set framework config */
|
|
@@ -655,6 +793,30 @@ interface RouterInterface extends EventEmitterInterface<RouterInterface> {
|
|
|
655
793
|
*/
|
|
656
794
|
onChanged?: (e?: RouteChangedEvent) => void;
|
|
657
795
|
}
|
|
796
|
+
/**
|
|
797
|
+
* Service event interface, triggered when request starts or ends.
|
|
798
|
+
* Includes begin/done/fail/end event types.
|
|
799
|
+
*/
|
|
800
|
+
interface ServiceEvent extends ChangeEvent {
|
|
801
|
+
/**
|
|
802
|
+
* Data payload object carrying this request's data.
|
|
803
|
+
*/
|
|
804
|
+
readonly payload: PayloadInterface;
|
|
805
|
+
/**
|
|
806
|
+
* Error object, present if request throws an error, otherwise null.
|
|
807
|
+
*/
|
|
808
|
+
readonly error: object | string | null;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* View event interface carrying the ID of the node that triggered the event.
|
|
812
|
+
* Carried in DOM events bound via @event attribute.
|
|
813
|
+
*/
|
|
814
|
+
interface ViewEvent extends ChangeEvent {
|
|
815
|
+
/**
|
|
816
|
+
* DOM node ID that triggered the event.
|
|
817
|
+
*/
|
|
818
|
+
readonly id: string;
|
|
819
|
+
}
|
|
658
820
|
/**
|
|
659
821
|
* Frame static event interface carrying associated Frame instance.
|
|
660
822
|
* Carried in Frame's add/remove static events.
|
|
@@ -688,10 +850,10 @@ interface ViewInterface extends EventEmitterInterface<ViewInterface> {
|
|
|
688
850
|
/** Whether rendered at least once */
|
|
689
851
|
rendered?: boolean;
|
|
690
852
|
/**
|
|
691
|
-
* View template
|
|
692
|
-
*
|
|
853
|
+
* View template function. Receives data + viewId + refData and a set of
|
|
854
|
+
* encoder helpers wired in by the Updater, and returns the rendered HTML.
|
|
693
855
|
*/
|
|
694
|
-
template?:
|
|
856
|
+
template?: ViewTemplate;
|
|
695
857
|
/**
|
|
696
858
|
* Mixin object array for extending view functionality.
|
|
697
859
|
* Framework merges properties and methods from mixins into view prototype.
|
|
@@ -817,6 +979,7 @@ interface ViewInterface extends EventEmitterInterface<ViewInterface> {
|
|
|
817
979
|
* @param args Mixin object list
|
|
818
980
|
*/
|
|
819
981
|
merge?(...args: ExtendThisType<ViewInterface>[]): ViewInterface;
|
|
982
|
+
navigate?: (path: string, params?: Record<string, unknown>) => void;
|
|
820
983
|
}
|
|
821
984
|
type ExtendThisType<T> = Record<string, unknown> & ThisType<T>;
|
|
822
985
|
/**
|
|
@@ -936,7 +1099,7 @@ interface UpdaterInterface {
|
|
|
936
1099
|
* @param data Data object, e.g., `{ a: 1, b: 2 }`
|
|
937
1100
|
* @param excludes Set of keys to exclude from change tracking
|
|
938
1101
|
*/
|
|
939
|
-
set: (data: Record<string, unknown>, excludes?:
|
|
1102
|
+
set: (data: Record<string, unknown>, excludes?: ReadonlySet<string>) => UpdaterInterface;
|
|
940
1103
|
/**
|
|
941
1104
|
* Trigger page re-render.
|
|
942
1105
|
* After set, must explicitly call `digest()` to commit changes to page.
|
|
@@ -945,7 +1108,7 @@ interface UpdaterInterface {
|
|
|
945
1108
|
* @param excludes Set of keys to exclude from change tracking
|
|
946
1109
|
* @param callback Callback executed after render completes
|
|
947
1110
|
*/
|
|
948
|
-
digest: (data?: Record<string, unknown>, excludes?:
|
|
1111
|
+
digest: (data?: Record<string, unknown>, excludes?: ReadonlySet<string>, callback?: () => void) => void;
|
|
949
1112
|
/**
|
|
950
1113
|
* Save a snapshot of current data for altered() detection.
|
|
951
1114
|
* Works with `altered()` method to detect whether data has changed.
|
|
@@ -1002,10 +1165,9 @@ interface ChangeEvent {
|
|
|
1002
1165
|
*/
|
|
1003
1166
|
readonly type: string;
|
|
1004
1167
|
/**
|
|
1005
|
-
* Set
|
|
1006
|
-
* TODO: Optimize to Set data structure.
|
|
1168
|
+
* Set of changed data keys. Use `keys.has(name)` to check membership.
|
|
1007
1169
|
*/
|
|
1008
|
-
readonly keys?:
|
|
1170
|
+
readonly keys?: ReadonlySet<string>;
|
|
1009
1171
|
}
|
|
1010
1172
|
/**
|
|
1011
1173
|
* Event emitter interface providing on/off/fire methods for publish-subscribe pattern.
|
|
@@ -1038,6 +1200,11 @@ interface EventEmitterInterface<T = unknown> {
|
|
|
1038
1200
|
* Global state interface providing cross-view data sharing and data change notification capabilities.
|
|
1039
1201
|
* State is a singleton object managing app-level state data via get/set/digest.
|
|
1040
1202
|
* Supports `clean()` method to create a mixin for automatic cleanup on view destruction.
|
|
1203
|
+
*
|
|
1204
|
+
* Use State for SIMPLE cross-view data (lightweight shared values: counters,
|
|
1205
|
+
* toggles, page title, session info, etc.). For COMPLEX reactive state —
|
|
1206
|
+
* handlers, derived data, multi-instance isolation, or Proxy-based fine-grained
|
|
1207
|
+
* dependency tracking — use `defineStore` instead.
|
|
1041
1208
|
*/
|
|
1042
1209
|
interface StateInterface extends EventEmitterInterface<StateInterface> {
|
|
1043
1210
|
/**
|
|
@@ -1051,7 +1218,7 @@ interface StateInterface extends EventEmitterInterface<StateInterface> {
|
|
|
1051
1218
|
* @param data Data object, e.g., `{ a: 1, b: 2 }`
|
|
1052
1219
|
* @param excludes Set of keys to exclude from change tracking
|
|
1053
1220
|
*/
|
|
1054
|
-
set(data: Record<string, unknown>, excludes?:
|
|
1221
|
+
set(data: Record<string, unknown>, excludes?: ReadonlySet<string>): this;
|
|
1055
1222
|
/**
|
|
1056
1223
|
* Clean data for specified keys in State, can only be used in view's mixins.
|
|
1057
1224
|
* For example `mixins: [State.clean("a,b")]`.
|
|
@@ -1069,11 +1236,11 @@ interface StateInterface extends EventEmitterInterface<StateInterface> {
|
|
|
1069
1236
|
* @param data Optional data object, if provided calls `set()` first to set data
|
|
1070
1237
|
* @param excludes Set of keys to exclude from change tracking
|
|
1071
1238
|
*/
|
|
1072
|
-
digest(data?: Record<string, unknown>, excludes?:
|
|
1239
|
+
digest(data?: Record<string, unknown>, excludes?: ReadonlySet<string>): void;
|
|
1073
1240
|
/**
|
|
1074
|
-
*
|
|
1241
|
+
* Get the set of keys changed in the most recent digest.
|
|
1075
1242
|
*/
|
|
1076
|
-
diff: () =>
|
|
1243
|
+
diff: () => ReadonlySet<string>;
|
|
1077
1244
|
onChanged?: (e?: ChangeEvent) => void;
|
|
1078
1245
|
}
|
|
1079
1246
|
interface ServiceOptions {
|
|
@@ -1155,6 +1322,103 @@ interface ServiceMetaEntry {
|
|
|
1155
1322
|
/** Additional properties */
|
|
1156
1323
|
[key: string]: unknown;
|
|
1157
1324
|
}
|
|
1325
|
+
interface ServiceInternals {
|
|
1326
|
+
metaList: Record<string, ServiceMetaEntry>;
|
|
1327
|
+
payloadCache: CacheInterface<PayloadInterface>;
|
|
1328
|
+
pendingCacheKeys: Record<string, PendingCacheEntry>;
|
|
1329
|
+
syncFn: (payload: PayloadInterface, callback: () => void) => void;
|
|
1330
|
+
staticEmitter: EventEmitterInterface;
|
|
1331
|
+
}
|
|
1332
|
+
interface ServiceInterface {
|
|
1333
|
+
id: string;
|
|
1334
|
+
destroyed: number;
|
|
1335
|
+
busy: number;
|
|
1336
|
+
taskQueue: AnyFunc[];
|
|
1337
|
+
prevArgs: unknown[];
|
|
1338
|
+
emitter: EventEmitterInterface;
|
|
1339
|
+
internals: ServiceInternals;
|
|
1340
|
+
/**
|
|
1341
|
+
* Send all requests in parallel, execute done callback when all requests complete (success or failure).
|
|
1342
|
+
* If endpoint specifies cache and cache is valid, uses cached data directly.
|
|
1343
|
+
* @param metaList Endpoint name string, params object, or array of them
|
|
1344
|
+
* @param done Callback when all requests complete, first param is error array, followed by each endpoint's Payload
|
|
1345
|
+
*/
|
|
1346
|
+
all(metaList: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInterface;
|
|
1347
|
+
/**
|
|
1348
|
+
* Execute callback after each request succeeds, callback may be called multiple times.
|
|
1349
|
+
* @param metaList Endpoint name string, params object, or array of them
|
|
1350
|
+
* @param done Callback
|
|
1351
|
+
*/
|
|
1352
|
+
one(attrs: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInterface;
|
|
1353
|
+
/**
|
|
1354
|
+
* Similar to all, but always skips cache and forces actual requests.
|
|
1355
|
+
* @param metaList Endpoint name string, params object, or array of them
|
|
1356
|
+
* @param done Callback
|
|
1357
|
+
*/
|
|
1358
|
+
save(metaList: string | Record<string, unknown> | (string | Record<string, unknown>)[], done: AnyFunc): ServiceInterface;
|
|
1359
|
+
/**
|
|
1360
|
+
* Queue task for execution, executes next task after previous all/one/save task completes, similar to Promise chain.
|
|
1361
|
+
* @param callback Callback invoked after task completes
|
|
1362
|
+
*/
|
|
1363
|
+
enqueue(callback: AnyFunc): ServiceInterface;
|
|
1364
|
+
/**
|
|
1365
|
+
* Dequeue and execute next task in queue.
|
|
1366
|
+
*/
|
|
1367
|
+
dequeue(...args: unknown[]): void;
|
|
1368
|
+
/**
|
|
1369
|
+
* Destroy current Service instance, cannot send new requests or invoke callbacks after destruction.
|
|
1370
|
+
*/
|
|
1371
|
+
destroy(): void;
|
|
1372
|
+
/**
|
|
1373
|
+
* Add endpoint metadata, register one or more API endpoints.
|
|
1374
|
+
* @param metaList Endpoint metadata array, or single metadata object
|
|
1375
|
+
*/
|
|
1376
|
+
add(attrs: ServiceMetaEntry | ServiceMetaEntry[]): void;
|
|
1377
|
+
/**
|
|
1378
|
+
* Get metadata object.
|
|
1379
|
+
* @param attrs Endpoint metadata object or name string
|
|
1380
|
+
*/
|
|
1381
|
+
meta(attrs: string | Record<string, unknown>): ServiceMetaEntry;
|
|
1382
|
+
/**
|
|
1383
|
+
* Create Payload object from endpoint metadata.
|
|
1384
|
+
* @param meta Endpoint metadata object or name string
|
|
1385
|
+
*/
|
|
1386
|
+
create(meta: Record<string, unknown>): PayloadInterface;
|
|
1387
|
+
/**
|
|
1388
|
+
* Get or create Payload object from cache.
|
|
1389
|
+
* @param meta Endpoint metadata object
|
|
1390
|
+
* @param createNew Whether to create new Payload object; if false, prioritizes getting from cache
|
|
1391
|
+
*/
|
|
1392
|
+
get(meta: Record<string, unknown>, createNew?: boolean): {
|
|
1393
|
+
entity: PayloadInterface;
|
|
1394
|
+
needsUpdate: boolean;
|
|
1395
|
+
};
|
|
1396
|
+
/**
|
|
1397
|
+
* Get Payload object from cache, returns undefined if cache doesn't exist or has expired.
|
|
1398
|
+
* @param meta Endpoint metadata object
|
|
1399
|
+
*/
|
|
1400
|
+
cached(meta: Record<string, unknown>): PayloadInterface | undefined;
|
|
1401
|
+
/**
|
|
1402
|
+
* Clear cached data for specified endpoint.
|
|
1403
|
+
* @param names Comma-separated endpoint name string or string array
|
|
1404
|
+
*/
|
|
1405
|
+
clear(names: string | string[]): void;
|
|
1406
|
+
/**
|
|
1407
|
+
* Inherit to create new Service subclass, bind custom data sync function.
|
|
1408
|
+
* @param sync Method to sync data, typically exchanges data with server
|
|
1409
|
+
* @param cacheMax Maximum cache entries
|
|
1410
|
+
* @param cacheBuffer Cache buffer size
|
|
1411
|
+
*/
|
|
1412
|
+
extend(newSyncFn: (payload: PayloadInterface, callback: () => void) => void, newCacheMax?: number, newCacheBuffer?: number): ServiceInterface;
|
|
1413
|
+
/**
|
|
1414
|
+
* Triggered before endpoint sends request.
|
|
1415
|
+
*/
|
|
1416
|
+
onBegin?: (e?: ServiceEvent) => void;
|
|
1417
|
+
/**
|
|
1418
|
+
* Triggered when endpoint request completes, whether success or failure.
|
|
1419
|
+
*/
|
|
1420
|
+
onEnd?: (e?: ServiceEvent) => void;
|
|
1421
|
+
}
|
|
1158
1422
|
/** Cache info attached to Payload entity */
|
|
1159
1423
|
interface ServiceCacheInfo {
|
|
1160
1424
|
/** Endpoint name */
|
|
@@ -1170,13 +1434,27 @@ interface ServiceCacheInfo {
|
|
|
1170
1434
|
}
|
|
1171
1435
|
interface FrameworkInterface {
|
|
1172
1436
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
* -
|
|
1175
|
-
* -
|
|
1176
|
-
*
|
|
1177
|
-
*
|
|
1437
|
+
* Read framework configuration.
|
|
1438
|
+
* - Without arguments: returns the complete config object.
|
|
1439
|
+
* - With a key: returns just `config[key]` (untyped — use a generic to
|
|
1440
|
+
* constrain the return type if you know the key's shape).
|
|
1441
|
+
*
|
|
1442
|
+
* `getConfig` is a pure read — call `setConfig(patch)` to mutate.
|
|
1443
|
+
*/
|
|
1444
|
+
getConfig(): FrameworkConfig;
|
|
1445
|
+
getConfig<T = unknown>(key: string): T | undefined;
|
|
1446
|
+
/**
|
|
1447
|
+
* Merge a patch into the framework configuration and return the merged
|
|
1448
|
+
* config object. Replaces the dual-purpose overload of `config()`.
|
|
1449
|
+
*/
|
|
1450
|
+
setConfig<T extends object = Partial<FrameworkConfig>>(patch: Partial<FrameworkConfig> & T): FrameworkConfig & T;
|
|
1451
|
+
/**
|
|
1452
|
+
* @deprecated Use `getConfig()` / `getConfig(key)` for reads and
|
|
1453
|
+
* `setConfig(patch)` for writes. The overloaded `config()` blurred the
|
|
1454
|
+
* two and confused TypeScript inference; the split is a drop-in upgrade.
|
|
1178
1455
|
*/
|
|
1179
1456
|
config<T extends object = Partial<FrameworkConfig>>(cfg?: Partial<FrameworkConfig> & T): FrameworkConfig & T;
|
|
1457
|
+
/** @deprecated See above. */
|
|
1180
1458
|
config(key: string): unknown;
|
|
1181
1459
|
/**
|
|
1182
1460
|
* App initialization entry point, starts framework and renders root view.
|
|
@@ -1205,9 +1483,9 @@ interface FrameworkInterface {
|
|
|
1205
1483
|
* Example: `Framework.toUrl('/xxx/', {a:'b',c:'d'})` => `/xxx/?a=b&c=d`
|
|
1206
1484
|
* @param path Path string
|
|
1207
1485
|
* @param params Params object
|
|
1208
|
-
* @param keepEmpty Set of keys
|
|
1486
|
+
* @param keepEmpty Set of keys whose empty values should be preserved
|
|
1209
1487
|
*/
|
|
1210
|
-
toUrl(path: string, params?: Record<string, unknown>, keepEmpty?:
|
|
1488
|
+
toUrl(path: string, params?: Record<string, unknown>, keepEmpty?: Set<string>): string;
|
|
1211
1489
|
/**
|
|
1212
1490
|
* Parse URL string to path and params object.
|
|
1213
1491
|
* Example: `Framework.parseUrl('/xxx/?a=b&c=d')` => `{path:'/xxx/', params:{a:'b',c:'d'}}`
|
|
@@ -1408,11 +1686,29 @@ interface FrameworkConfig {
|
|
|
1408
1686
|
*/
|
|
1409
1687
|
unmatchedView?: string;
|
|
1410
1688
|
/**
|
|
1411
|
-
* Module require function
|
|
1689
|
+
* Module require function for asynchronous view loading.
|
|
1690
|
+
* Called by `Framework.use()` when a view class is not found in the registry.
|
|
1691
|
+
* Integrate with Webpack Module Federation or other dynamic loading strategies.
|
|
1692
|
+
*
|
|
1693
|
+
* @param names - Array of module names to load (e.g., `["remote-app/views/home"]`)
|
|
1694
|
+
* @param params - Optional parameters passed to the module initializer
|
|
1695
|
+
* @returns Promise resolving to an array of loaded modules, or undefined if not available
|
|
1412
1696
|
*/
|
|
1413
|
-
require?: (names: string[], params?: Record<string, unknown>) => Promise<unknown> | undefined;
|
|
1697
|
+
require?: (names: string[], params?: Record<string, unknown>) => Promise<unknown[]> | undefined;
|
|
1414
1698
|
/** Skip view rendered check */
|
|
1415
1699
|
skipViewRendered?: boolean;
|
|
1700
|
+
/**
|
|
1701
|
+
* Project name of the current application.
|
|
1702
|
+
* Used by the micro-frontend bridge to determine if a view path
|
|
1703
|
+
* belongs to the current project or a remote project.
|
|
1704
|
+
*/
|
|
1705
|
+
projectName?: string;
|
|
1706
|
+
/**
|
|
1707
|
+
* Cross-site (micro-frontend) configuration list.
|
|
1708
|
+
* Defines remote projects that can be loaded via Module Federation.
|
|
1709
|
+
* Also accessible via `window.crossConfigs` for build-time injection.
|
|
1710
|
+
*/
|
|
1711
|
+
crossConfigs?: CrossSiteConfig[];
|
|
1416
1712
|
/** Dynamic config access, custom config items */
|
|
1417
1713
|
[key: string]: unknown;
|
|
1418
1714
|
}
|
|
@@ -1422,6 +1718,23 @@ interface RouteViewConfig {
|
|
|
1422
1718
|
/** Additional properties merged into location */
|
|
1423
1719
|
[key: string]: unknown;
|
|
1424
1720
|
}
|
|
1721
|
+
/**
|
|
1722
|
+
* Configuration for a remote (cross-site) project in the micro-frontend setup.
|
|
1723
|
+
* Each entry defines how to load views from a different project via Module Federation.
|
|
1724
|
+
*/
|
|
1725
|
+
interface CrossSiteConfig {
|
|
1726
|
+
/** Project name, used as the prefix in view paths (e.g., "remote-app" in "remote-app/views/home") */
|
|
1727
|
+
projectName: string;
|
|
1728
|
+
/**
|
|
1729
|
+
* Remote source URL or Module Federation remote name.
|
|
1730
|
+
* For Webpack MF: the remote entry URL (e.g., "remote_app@//cdn.example.com/remote-app/remoteEntry.js")
|
|
1731
|
+
*/
|
|
1732
|
+
source: string;
|
|
1733
|
+
/** Optional API host for the remote project */
|
|
1734
|
+
apiHost?: string;
|
|
1735
|
+
/** Optional business code for multi-tenant scenarios */
|
|
1736
|
+
bizCode?: string;
|
|
1737
|
+
}
|
|
1425
1738
|
/** Element with VDOM diff cached compare key */
|
|
1426
1739
|
interface VdomElement extends Element {
|
|
1427
1740
|
/** Whether compare key is cached */
|
|
@@ -1469,7 +1782,7 @@ declare function generateId(prefix?: string): string;
|
|
|
1469
1782
|
declare function syncCounter(val: number): void;
|
|
1470
1783
|
declare function noop(): void;
|
|
1471
1784
|
/** Safe hasOwnProperty check */
|
|
1472
|
-
declare function
|
|
1785
|
+
declare function hasOwnProperty<T extends object>(owner: T | undefined | null, prop: PropertyKey): boolean;
|
|
1473
1786
|
/** Get object keys (own enumerable) */
|
|
1474
1787
|
declare function keys<T extends object>(obj: T): string[];
|
|
1475
1788
|
/** Assign properties from sources to target (like Object.assign but safer) */
|
|
@@ -1483,11 +1796,7 @@ declare function funcWithTry(fns: AnyFunc | AnyFunc[], args: unknown[], context:
|
|
|
1483
1796
|
* Set newData into oldData, tracking changed keys.
|
|
1484
1797
|
* Returns whether any value changed.
|
|
1485
1798
|
*/
|
|
1486
|
-
declare function setData(newData: Record<string, unknown>, oldData: Record<string, unknown>, changedKeys:
|
|
1487
|
-
/**
|
|
1488
|
-
* Translate data references: if a value starts with SPLITTER, replace it
|
|
1489
|
-
* with the corresponding value from the data object.
|
|
1490
|
-
*/
|
|
1799
|
+
declare function setData(newData: Record<string, unknown>, oldData: Record<string, unknown>, changedKeys: Set<string>, excludes: ReadonlySet<string>): boolean;
|
|
1491
1800
|
declare function translateData(data: object, value: unknown): unknown;
|
|
1492
1801
|
/** Get element by ID, or return the element itself if already an element */
|
|
1493
1802
|
declare function getById(id: string | Element | null): Element | null;
|
|
@@ -1503,13 +1812,16 @@ declare function nodeInside(a: string | HTMLElement, b: string | HTMLElement): b
|
|
|
1503
1812
|
/**
|
|
1504
1813
|
* Parse URI string into path and params object.
|
|
1505
1814
|
* e.g. "/xxx/?a=b&c=d" => { path: "/xxx/", params: { a: "b", c: "d" } }
|
|
1815
|
+
*
|
|
1816
|
+
* The accumulator is function-local, so nested / re-entrant calls
|
|
1817
|
+
* (e.g. invoking `parseUri` again inside a replace callback) are safe.
|
|
1506
1818
|
*/
|
|
1507
1819
|
declare function parseUri(uri: string): ParsedUri;
|
|
1508
1820
|
/**
|
|
1509
1821
|
* Convert path and params to URI string.
|
|
1510
1822
|
* e.g. toUri("/xxx/", { a: "b", c: "d" }) => "/xxx/?a=b&c=d"
|
|
1511
1823
|
*/
|
|
1512
|
-
declare function toUri(path: string, params: Record<string, unknown>,
|
|
1824
|
+
declare function toUri(path: string, params: Record<string, unknown>, keepEmpty?: ReadonlySet<string>): string;
|
|
1513
1825
|
/**
|
|
1514
1826
|
* Convert array to map/hash object.
|
|
1515
1827
|
* For simple arrays, counts occurrences.
|
|
@@ -1518,18 +1830,10 @@ declare function toUri(path: string, params: Record<string, unknown>, keepEmptyO
|
|
|
1518
1830
|
declare function toMap<T>(list: T[] | null | undefined, key?: keyof T): Record<string, T | number>;
|
|
1519
1831
|
/** Get current timestamp */
|
|
1520
1832
|
declare function now(): number;
|
|
1521
|
-
/** Constructable function type */
|
|
1522
|
-
type Constructable = new (...args: never[]) => unknown;
|
|
1523
|
-
/**
|
|
1524
|
-
* Implement classical inheritance with prototype chain.
|
|
1525
|
-
* This is the only place where we touch constructor internals -
|
|
1526
|
-
* it's a low-level framework utility for View.extend.
|
|
1527
|
-
*/
|
|
1528
|
-
declare function classExtend<Proto extends object, Statics extends object>(make: Constructable, base: Constructable, props: Proto, statics: Statics): void;
|
|
1529
1833
|
|
|
1530
1834
|
/** Internal splitter character (invisible, used as namespace separator) */
|
|
1531
1835
|
declare const SPLITTER = "\u001E";
|
|
1532
|
-
declare const
|
|
1836
|
+
declare const RouterEvents: {
|
|
1533
1837
|
CHANGE: string;
|
|
1534
1838
|
CHANGED: string;
|
|
1535
1839
|
PAGE_UNLOAD: string;
|
|
@@ -1564,23 +1868,27 @@ declare function applyStyle(styleIdOrPairs: string | string[], css?: string): ()
|
|
|
1564
1868
|
/**
|
|
1565
1869
|
* Mark/Unmark: signature-based lifecycle tracking for async callbacks.
|
|
1566
1870
|
*
|
|
1567
|
-
* mark() returns a validity checker
|
|
1568
|
-
* (e.g. view re-
|
|
1871
|
+
* `mark(host, key)` returns a validity checker. The checker returns `false`
|
|
1872
|
+
* once the host is unmarked (e.g. when a view re-renders or is destroyed),
|
|
1873
|
+
* so stale async callbacks can short-circuit and skip work.
|
|
1874
|
+
*
|
|
1875
|
+
* State is stored in a module-level WeakMap, not on the host object, so
|
|
1876
|
+
* `mark/unmark` never pollutes user objects with magic keys, never breaks
|
|
1877
|
+
* on `Object.freeze`-ed inputs, and never shows up in debug snapshots.
|
|
1569
1878
|
*/
|
|
1570
1879
|
/**
|
|
1571
1880
|
* Create a mark for tracking async callback validity.
|
|
1572
|
-
* Returns a function that
|
|
1881
|
+
* Returns a function that returns true while the mark is still valid.
|
|
1573
1882
|
*
|
|
1574
|
-
* @param host - Object to
|
|
1575
|
-
* @param key
|
|
1576
|
-
* @returns Checker function that returns true if mark is still valid
|
|
1883
|
+
* @param host - Object to associate the mark with (typically a view)
|
|
1884
|
+
* @param key - Key to track (typically "render" or a specific async-op identifier)
|
|
1577
1885
|
*/
|
|
1578
1886
|
declare function mark$1(host: object, key: string): () => boolean;
|
|
1579
1887
|
/**
|
|
1580
|
-
* Clear all marks for a host object, invalidating
|
|
1888
|
+
* Clear all marks for a host object, invalidating every existing checker.
|
|
1581
1889
|
* Called when a view re-renders or is destroyed.
|
|
1582
1890
|
*
|
|
1583
|
-
* @param host - Object whose marks should be
|
|
1891
|
+
* @param host - Object whose marks should be invalidated
|
|
1584
1892
|
*/
|
|
1585
1893
|
declare function unmark$1(host: object): void;
|
|
1586
1894
|
|
|
@@ -1624,6 +1932,56 @@ declare const Router: RouterInterface;
|
|
|
1624
1932
|
/** Mark framework as booted (called by Framework.boot) */
|
|
1625
1933
|
declare function markRouterBooted(): void;
|
|
1626
1934
|
|
|
1935
|
+
/**
|
|
1936
|
+
* Module loader: async view loading via FrameworkConfig.require or dynamic import.
|
|
1937
|
+
*
|
|
1938
|
+
* Extracted from framework.ts to avoid circular dependency with frame.ts.
|
|
1939
|
+
* Both framework.ts and frame.ts import from this module.
|
|
1940
|
+
*/
|
|
1941
|
+
|
|
1942
|
+
/** Framework configuration */
|
|
1943
|
+
declare const config: FrameworkConfig;
|
|
1944
|
+
/**
|
|
1945
|
+
* Load modules via the configured require function or dynamic import fallback.
|
|
1946
|
+
*
|
|
1947
|
+
* Two calling conventions:
|
|
1948
|
+
* 1. `use(name | name[], callback)`
|
|
1949
|
+
* 2. `use(name | name[])` — returns Promise<unknown[]> (no callback)
|
|
1950
|
+
*
|
|
1951
|
+
* When `FrameworkConfig.require` is configured, delegates to it (e.g., Webpack Module Federation).
|
|
1952
|
+
* When not configured, falls back to `dynamic import()` for ESM-based loading.
|
|
1953
|
+
*/
|
|
1954
|
+
declare function use(names: string | string[], callback?: (...modules: unknown[]) => void): Promise<unknown[]>;
|
|
1955
|
+
|
|
1956
|
+
/**
|
|
1957
|
+
* CrossSite: Micro-frontend bridge View for cross-project view loading.
|
|
1958
|
+
*
|
|
1959
|
+
* For Lark + Webpack Module Federation.
|
|
1960
|
+
* Provides skeleton rendering, prepare preloading, assign reuse, and remote view mounting.
|
|
1961
|
+
*
|
|
1962
|
+
* Usage (in host project):
|
|
1963
|
+
* 1. Register CrossSite as the bridge view for cross-site paths:
|
|
1964
|
+
* registerViewClass('cross-site', CrossSite);
|
|
1965
|
+
* 2. Use v-lark="cross-site?view=remote-app/views/home¶m=1" in template
|
|
1966
|
+
* 3. CrossSite loads the remote project's prepare module, then mounts the actual view
|
|
1967
|
+
*/
|
|
1968
|
+
|
|
1969
|
+
/**
|
|
1970
|
+
* Reset the projects map cache (useful when crossConfigs change at runtime).
|
|
1971
|
+
*/
|
|
1972
|
+
declare function resetProjectsMap(): void;
|
|
1973
|
+
/**
|
|
1974
|
+
* CrossSite bridge View for micro-frontend integration.
|
|
1975
|
+
*
|
|
1976
|
+
* Flow:
|
|
1977
|
+
* 1. CrossSite is mounted as a regular view (registered as "cross-site")
|
|
1978
|
+
* 2. render() shows skeleton template with a child container
|
|
1979
|
+
* 3. updateView() loads the remote project's prepare module
|
|
1980
|
+
* 4. Once loaded, mounts the actual remote view into the child container
|
|
1981
|
+
* 5. On re-assign (same view path), calls assign on the remote view instead of re-mounting
|
|
1982
|
+
*/
|
|
1983
|
+
declare const CrossSite: typeof View;
|
|
1984
|
+
|
|
1627
1985
|
/**
|
|
1628
1986
|
* Unmount frames within a DOM node.
|
|
1629
1987
|
*/
|
|
@@ -1640,6 +1998,8 @@ declare function vdomGetNode(html: string, refNode: Element): Element;
|
|
|
1640
1998
|
declare function vdomGetCompareKey(node: ChildNode): string | undefined;
|
|
1641
1999
|
/**
|
|
1642
2000
|
* Special diff for form elements (value, checked, selected).
|
|
2001
|
+
* Form elements carry state on the DOM node (e.g. `input.value`) that isn't
|
|
2002
|
+
* reflected in attributes, so we have to sync those properties separately.
|
|
1643
2003
|
*/
|
|
1644
2004
|
declare function vdomSpecialDiff(oldNode: ChildNode, newNode: ChildNode): number;
|
|
1645
2005
|
/**
|
|
@@ -1649,11 +2009,11 @@ declare function vdomSetAttributes(oldNode: Element, newNode: Element, ref: VDom
|
|
|
1649
2009
|
/**
|
|
1650
2010
|
* Set child nodes from new parent onto old parent using keyed diff algorithm.
|
|
1651
2011
|
*/
|
|
1652
|
-
declare function vdomSetChildNodes(oldParent: Element, newParent: Element, ref: VDomRef, frame: FrameInterface, keys_?:
|
|
2012
|
+
declare function vdomSetChildNodes(oldParent: Element, newParent: Element, ref: VDomRef, frame: FrameInterface, keys_?: ReadonlySet<string>): void;
|
|
1653
2013
|
/**
|
|
1654
2014
|
* Diff two DOM nodes and apply changes.
|
|
1655
2015
|
*/
|
|
1656
|
-
declare function vdomSetNode(oldNode: ChildNode, newNode: ChildNode, oldParent: Element, ref: VDomRef, frame: FrameInterface, keys_?:
|
|
2016
|
+
declare function vdomSetNode(oldNode: ChildNode, newNode: ChildNode, oldParent: Element, ref: VDomRef, frame: FrameInterface, keys_?: ReadonlySet<string>): void;
|
|
1657
2017
|
/**
|
|
1658
2018
|
* Create an empty VDomRef for tracking diff operations.
|
|
1659
2019
|
*/
|
|
@@ -1691,10 +2051,16 @@ declare class Updater implements UpdaterInterface {
|
|
|
1691
2051
|
private changedKeys;
|
|
1692
2052
|
/** Whether data has changed since last digest */
|
|
1693
2053
|
private hasChangedFlag;
|
|
1694
|
-
/**
|
|
2054
|
+
/**
|
|
2055
|
+
* Digesting queue: supports re-digest during digest.
|
|
2056
|
+
* Holds pending callbacks; `null` is used as a sentinel marking the start
|
|
2057
|
+
* of an active digest cycle, so `runDigest` can detect re-entrant calls.
|
|
2058
|
+
*/
|
|
1695
2059
|
private digestingQueue;
|
|
1696
|
-
/**
|
|
1697
|
-
private
|
|
2060
|
+
/** Monotonically increasing version, bumped each time data actually changes. */
|
|
2061
|
+
private version;
|
|
2062
|
+
/** Snapshot of `version` taken by `snapshot()`, used by `altered()`. */
|
|
2063
|
+
private snapshotVersion;
|
|
1698
2064
|
constructor(viewId: string);
|
|
1699
2065
|
/**
|
|
1700
2066
|
* Get data by key.
|
|
@@ -1705,7 +2071,7 @@ declare class Updater implements UpdaterInterface {
|
|
|
1705
2071
|
* Set data, tracking changed keys.
|
|
1706
2072
|
* Returns this for chaining.
|
|
1707
2073
|
*/
|
|
1708
|
-
set(data: Record<string, unknown>, excludes?:
|
|
2074
|
+
set(data: Record<string, unknown>, excludes?: ReadonlySet<string>): this;
|
|
1709
2075
|
/**
|
|
1710
2076
|
* Detect changes and trigger VDOM re-render.
|
|
1711
2077
|
*
|
|
@@ -1717,31 +2083,44 @@ declare class Updater implements UpdaterInterface {
|
|
|
1717
2083
|
* 5. Call endUpdate on views that need re-rendering
|
|
1718
2084
|
* 6. Support re-digest during digest via queue
|
|
1719
2085
|
*/
|
|
1720
|
-
digest(data?: Record<string, unknown>, excludes?:
|
|
2086
|
+
digest(data?: Record<string, unknown>, excludes?: ReadonlySet<string>, callback?: () => void): void;
|
|
1721
2087
|
/**
|
|
1722
2088
|
* Core digest execution.
|
|
1723
2089
|
*/
|
|
1724
2090
|
private runDigest;
|
|
1725
2091
|
/**
|
|
1726
|
-
* Save a snapshot of current data for altered() detection.
|
|
2092
|
+
* Save a snapshot of the current data version for `altered()` detection.
|
|
2093
|
+
* Cheap O(1) — records the current monotonic version, no serialization.
|
|
1727
2094
|
*/
|
|
1728
2095
|
snapshot(): this;
|
|
1729
2096
|
/**
|
|
1730
|
-
* Check
|
|
2097
|
+
* Check whether data has changed since the last snapshot.
|
|
2098
|
+
* Returns undefined when no snapshot has been taken yet.
|
|
1731
2099
|
*/
|
|
1732
2100
|
altered(): boolean | undefined;
|
|
1733
2101
|
/**
|
|
1734
|
-
* Translate
|
|
2102
|
+
* Translate a refData reference back to its original value.
|
|
2103
|
+
*
|
|
2104
|
+
* The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
|
|
2105
|
+
* emitted by `updaterRef`. We require that exact shape so a user-supplied
|
|
2106
|
+
* string that merely begins with SPLITTER is never accidentally resolved
|
|
2107
|
+
* (or mishandled as a "missing ref").
|
|
1735
2108
|
*/
|
|
1736
2109
|
translate(data: unknown): unknown;
|
|
1737
2110
|
/**
|
|
1738
|
-
*
|
|
2111
|
+
* Resolve a dotted property path against refData.
|
|
2112
|
+
*
|
|
2113
|
+
* Only safe property-path syntax is supported: `a`, `a.b`, `a.b.c`.
|
|
2114
|
+
* Numeric literals (e.g. `1`, `1.5`) are returned as numbers. Anything else
|
|
2115
|
+
* returns `undefined` — we no longer evaluate arbitrary JavaScript via
|
|
2116
|
+
* `new Function`, so the method is CSP-safe and cannot be used as an
|
|
2117
|
+
* injection vector.
|
|
1739
2118
|
*/
|
|
1740
2119
|
parse(expr: string): unknown;
|
|
1741
2120
|
/**
|
|
1742
|
-
* Get
|
|
2121
|
+
* Get the set of keys changed since the last digest (for external inspection).
|
|
1743
2122
|
*/
|
|
1744
|
-
getChangedKeys():
|
|
2123
|
+
getChangedKeys(): ReadonlySet<string>;
|
|
1745
2124
|
}
|
|
1746
2125
|
|
|
1747
2126
|
/**
|
|
@@ -1898,10 +2277,20 @@ declare class Service {
|
|
|
1898
2277
|
static fire(event: string, data?: Record<string, unknown>): void;
|
|
1899
2278
|
/**
|
|
1900
2279
|
* Create a new Service subclass with a custom sync function.
|
|
1901
|
-
*
|
|
1902
|
-
*
|
|
2280
|
+
*
|
|
2281
|
+
* Each subclass gets its OWN copies of every per-type static field
|
|
2282
|
+
* (`_metaList`, `_payloadCache`, `_pendingCacheKeys`, `_syncFn`,
|
|
2283
|
+
* `_staticEmitter`, `_cacheMax`, `_cacheBuffer`) via `static override`.
|
|
2284
|
+
* This is intentional: it ensures that endpoint metadata, cache state,
|
|
2285
|
+
* in-flight dedup keys, and event subscribers are fully isolated between
|
|
2286
|
+
* different Service types, even when one extends another.
|
|
2287
|
+
*
|
|
2288
|
+
* **Do not refactor these `static override` declarations away** — sharing
|
|
2289
|
+
* them through prototype inheritance would let endpoints registered on one
|
|
2290
|
+
* subclass leak into another, and the LFU cache evictions of one type
|
|
2291
|
+
* would race with those of another.
|
|
1903
2292
|
*/
|
|
1904
|
-
static extend(newSyncFn: (payload: Payload, callback: () => void) => void, newCacheMax?: number, newCacheBuffer?: number): typeof Service;
|
|
2293
|
+
static extend(this: typeof Service, newSyncFn: (payload: Payload, callback: () => void) => void, newCacheMax?: number, newCacheBuffer?: number): typeof Service;
|
|
1905
2294
|
}
|
|
1906
2295
|
|
|
1907
2296
|
/**
|
|
@@ -1939,11 +2328,18 @@ declare const EventDelegator: {
|
|
|
1939
2328
|
declare const Framework: FrameworkInterface;
|
|
1940
2329
|
|
|
1941
2330
|
/**
|
|
1942
|
-
* @lark/
|
|
2331
|
+
* @lark.js/mvc Store
|
|
1943
2332
|
*
|
|
1944
2333
|
* Reactive state management with Proxy-based dependency tracking.
|
|
1945
2334
|
* Adapted for Lark / React / Node.js.
|
|
1946
2335
|
*
|
|
2336
|
+
* Store is the recommended choice for COMPLEX cross-view state:
|
|
2337
|
+
* reactive handlers, derived data, multi-instance isolation (`multi()`),
|
|
2338
|
+
* store-internal reactions (inner `observe`), and Proxy-based fine-grained
|
|
2339
|
+
* dependency tracking. For SIMPLE shared values (counters, toggles, page
|
|
2340
|
+
* title, session info, etc.) prefer `State` from `./state` — fewer concepts
|
|
2341
|
+
* and no Proxy overhead.
|
|
2342
|
+
*
|
|
1947
2343
|
* Core concepts:
|
|
1948
2344
|
* - createState: Proxy-based deep reactive state
|
|
1949
2345
|
* - track/trigger/clear: publish-subscribe dependency tracking
|
|
@@ -2018,6 +2414,29 @@ declare const _stateKeys: unique symbol;
|
|
|
2018
2414
|
declare const _storeState: unique symbol;
|
|
2019
2415
|
declare const _storeDefScheduler: unique symbol;
|
|
2020
2416
|
declare const _storeProxy: unique symbol;
|
|
2417
|
+
declare const _computedKeys: unique symbol;
|
|
2418
|
+
/**
|
|
2419
|
+
* Declare a derived (computed) store property.
|
|
2420
|
+
*
|
|
2421
|
+
* Usage (inside a `defineStore` creator):
|
|
2422
|
+
*
|
|
2423
|
+
* ```ts
|
|
2424
|
+
* defineStore("count", (store, { computed }) => ({
|
|
2425
|
+
* count: 0,
|
|
2426
|
+
* doubled: computed(["count"], () => store.count * 2),
|
|
2427
|
+
* increment() { store.count++ },
|
|
2428
|
+
* }));
|
|
2429
|
+
* ```
|
|
2430
|
+
*
|
|
2431
|
+
* `deps` lists the state keys the computed reads. Whenever any of those keys
|
|
2432
|
+
* changes, the computed function re-runs and the new value flows out through
|
|
2433
|
+
* the store like a regular state update — meaning views that
|
|
2434
|
+
* `store.observe(this, ["doubled"])` re-render automatically.
|
|
2435
|
+
*
|
|
2436
|
+
* The returned value is typed as `T`, so the store body still type-checks as
|
|
2437
|
+
* `{ doubled: number; ... }`. Writes to a computed key are ignored at runtime.
|
|
2438
|
+
*/
|
|
2439
|
+
declare function computed<T>(deps: readonly string[], fn: () => T): T;
|
|
2021
2440
|
declare abstract class BaseStore {
|
|
2022
2441
|
[_storeName]: string;
|
|
2023
2442
|
[_storeStatus]: StoreStatus;
|
|
@@ -2025,6 +2444,7 @@ declare abstract class BaseStore {
|
|
|
2025
2444
|
[_originState]: Record<string, unknown>;
|
|
2026
2445
|
[_stateKeys]: string[];
|
|
2027
2446
|
[_storeState]: Record<string, unknown>;
|
|
2447
|
+
[_computedKeys]: Set<string>;
|
|
2028
2448
|
[_storeDefScheduler]: () => Queue;
|
|
2029
2449
|
private [_outerStore];
|
|
2030
2450
|
[_storeBoot](): Record<string, unknown>;
|
|
@@ -2056,13 +2476,22 @@ interface NodeStoreMethods {
|
|
|
2056
2476
|
observe: (key: string, callback: AnyFunc, immediate?: boolean) => () => void;
|
|
2057
2477
|
}
|
|
2058
2478
|
interface StoreMethods {
|
|
2059
|
-
|
|
2479
|
+
/**
|
|
2480
|
+
* Subscribe a view to store changes.
|
|
2481
|
+
*
|
|
2482
|
+
* - `store.observe(view)` — observe every state key (D5 default).
|
|
2483
|
+
* - `store.observe(view, ["k1", "k2"])` — observe specific keys only.
|
|
2484
|
+
* - `store.observe(view, ["k1"], (changes) => ...)` — explicit callback.
|
|
2485
|
+
* - `store.observe(undefined, ["k1"], cb)` — inner observe (no view binding).
|
|
2486
|
+
*/
|
|
2487
|
+
observe: (view: LarkView | undefined, keys?: (string | ObservePayload)[] | (() => (string | ObservePayload)[]), defCallback?: (changedMap: Record<string, unknown>) => void) => () => void;
|
|
2060
2488
|
}
|
|
2061
2489
|
/** Detect platform from a component instance */
|
|
2062
2490
|
declare const getPlatform: (comp: unknown) => Platform | undefined;
|
|
2063
2491
|
declare const extendApis: {
|
|
2064
2492
|
lazySet: typeof lazySet;
|
|
2065
2493
|
shallowSet: typeof shallowSet;
|
|
2494
|
+
computed: typeof computed;
|
|
2066
2495
|
};
|
|
2067
2496
|
/** Inner store type available inside defineStore creator */
|
|
2068
2497
|
type InnerStore<S = Record<string, unknown>> = S & StoreMethods;
|
|
@@ -2139,8 +2568,16 @@ interface SerializedFrameTree {
|
|
|
2139
2568
|
/** Root element ID */
|
|
2140
2569
|
rootId: string;
|
|
2141
2570
|
}
|
|
2571
|
+
declare const FrameVisualBridge: {
|
|
2572
|
+
MSG_PING: string;
|
|
2573
|
+
MSG_PONG: string;
|
|
2574
|
+
MSG_REQUEST_TREE: string;
|
|
2575
|
+
MSG_TREE: string;
|
|
2576
|
+
MSG_TREE_DELTA: string;
|
|
2577
|
+
};
|
|
2142
2578
|
/**
|
|
2143
2579
|
* Serialize the entire Frame tree starting from root.
|
|
2580
|
+
* Returns an empty snapshot if the app hasn't booted yet.
|
|
2144
2581
|
*/
|
|
2145
2582
|
declare function serializeFrameTree(): SerializedFrameTree;
|
|
2146
2583
|
/**
|
|
@@ -2153,7 +2590,7 @@ declare function serializeFrameTree(): SerializedFrameTree;
|
|
|
2153
2590
|
declare function installFrameVisualizerBridge(): void;
|
|
2154
2591
|
|
|
2155
2592
|
/**
|
|
2156
|
-
* @lark/
|
|
2593
|
+
* @lark.js/mvc Template Compiler
|
|
2157
2594
|
*
|
|
2158
2595
|
* convertArtSyntax() ({{}} → <% %>)
|
|
2159
2596
|
* processViewEvents() (@event prefix + param encoding)
|
|
@@ -2189,7 +2626,7 @@ declare function installFrameVisualizerBridge(): void;
|
|
|
2189
2626
|
* This is the main entry point for both Vite and Webpack loaders.
|
|
2190
2627
|
*
|
|
2191
2628
|
* The output is an ES module that exports a function with the signature:
|
|
2192
|
-
* (data,
|
|
2629
|
+
* (data, viewId, refData) => string
|
|
2193
2630
|
*
|
|
2194
2631
|
* Internally it calls the compiled template function with the standard
|
|
2195
2632
|
* signature: ($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)
|
|
@@ -2217,4 +2654,4 @@ declare function compileTemplate(source: string, options?: CompileOptions): stri
|
|
|
2217
2654
|
*/
|
|
2218
2655
|
declare function extractGlobalVars(source: string): string[];
|
|
2219
2656
|
|
|
2220
|
-
export { CALL_BREAK_TIME, Cache, type CacheEntry, type CacheOptions, type CompileOptions, type
|
|
2657
|
+
export { type AnyFunc, CALL_BREAK_TIME, Cache, type CacheEntry, type CacheInterface, type CacheOptions, type ChangeEvent, type CompileOptions, CrossSite, type CrossSiteConfig, EVENT_METHOD_REGEXP, EventDelegator, EventEmitter, type EventEmitterInterface, type EventListenerEntry, Frame, type FrameBoundElement, type FrameInterface, type FrameInvokeEntry, type FrameStaticEvent, FrameVisualBridge, Framework, type FrameworkConfig, type FrameworkInterface, LARK_VIEW, type LarkUseStore, type Location, type LocationDiff, type MixinEventHandler, type NodeUseStore, type ObservePayload, type ParamDiff, type ParsedUri, Payload, type PayloadEntry, type PayloadInterface, type PendingCacheEntry, Platform, RouterEvents as ROUTER_EVENTS, type ReactUseStore, type RouteChangeEvent, type RouteChangedEvent, type RouteViewConfig, Router, type RouterInterface, SPLITTER, type SerializedFrameNode, type SerializedFrameTree, type SerializedViewInfo, Service, type ServiceCacheInfo, type ServiceEntry, type ServiceEvent, type ServiceInterface, type ServiceMetaEntry, type ServiceOptions, State, type StateInterface, type StoreConfig, type StoreMethods, TAG_NAME_REGEXP, Updater, type UpdaterInterface, type VDomOp, type VDomRef, VIEW_EVENT_METHOD_REGEXP, type VdomElement, View, type ViewEvent, type ViewEventSelectorEntry, type ViewGlobalEventEntry, type ViewInterface, type ViewLocationObserved, type ViewObserveLocation, type ViewResourceEntry, type ViewTemplate, type VoidFunc, applyIdUpdates, applyStyle, applyVdomOps, assign, cell, cloneData, cloneStore, compileTemplate, computed, createState, createVdomRef, defineStore, defineView, delStore, encodeHTML, encodeQ, encodeSafe, encodeURIExtra, ensureElementId, extractGlobalVars, config as frameworkConfig, funcWithTry, generateId, getAttribute, getById, getPlatform, getStore, getUseStore, hasOwnProperty, installFrameVisualizerBridge, invalidateViewClass, isPlainObject, isPrimitive, isPrimitiveOrFunc, isState, isStoreActive, keys, lazySet, mark$1 as mark, markBooted, markRouterBooted, multi, nextCounter, nodeInside, noop, now, observeCell, parseUri, registerViewClass, resetProjectsMap, safeguard, serializeFrameTree, setData, shallowSet, mark as storeMark, unmark as storeUnmark, syncCounter, toMap, toUri, translateData, unmark$1 as unmark, use, vdomGetCompareKey, vdomGetNode, vdomSetAttributes, vdomSetChildNodes, vdomSetNode, vdomSpecialDiff, vdomUnmountFrames };
|