@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.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
2
|
var globalCounter = 0;
|
|
3
3
|
var SPLITTER = "";
|
|
4
|
-
var
|
|
4
|
+
var RouterEvents = {
|
|
5
5
|
CHANGE: "change",
|
|
6
6
|
CHANGED: "changed",
|
|
7
7
|
PAGE_UNLOAD: "page_unload"
|
|
8
8
|
};
|
|
9
|
-
var
|
|
9
|
+
var LarkInnerKeys = {
|
|
10
10
|
/** Attribute name: ldk (static key for skipping VDOM diff) */
|
|
11
11
|
DIFF_KEY: "ldk",
|
|
12
12
|
/** Attribute name: lak (static attribute key) */
|
|
@@ -53,13 +53,13 @@ function syncCounter(val) {
|
|
|
53
53
|
}
|
|
54
54
|
function noop() {
|
|
55
55
|
}
|
|
56
|
-
function
|
|
56
|
+
function hasOwnProperty(owner, prop) {
|
|
57
57
|
return owner != null && Object.prototype.hasOwnProperty.call(owner, prop);
|
|
58
58
|
}
|
|
59
59
|
function keys(obj) {
|
|
60
60
|
const result = [];
|
|
61
61
|
for (const p in obj) {
|
|
62
|
-
if (
|
|
62
|
+
if (hasOwnProperty(obj, p)) {
|
|
63
63
|
result.push(p);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
@@ -69,7 +69,7 @@ function assign(target, ...sources) {
|
|
|
69
69
|
for (const source of sources) {
|
|
70
70
|
if (source) {
|
|
71
71
|
for (const p in source) {
|
|
72
|
-
if (
|
|
72
|
+
if (hasOwnProperty(source, p)) {
|
|
73
73
|
target[p] = source[p];
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -82,21 +82,22 @@ function funcWithTry(fns, args, context, configError) {
|
|
|
82
82
|
let ret;
|
|
83
83
|
for (const fn of fnArray) {
|
|
84
84
|
try {
|
|
85
|
-
ret =
|
|
85
|
+
ret = fn.apply(context, args);
|
|
86
86
|
} catch (e) {
|
|
87
87
|
configError?.(e);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
return ret;
|
|
91
91
|
}
|
|
92
|
+
var EMPTY_STRING_SET = /* @__PURE__ */ new Set();
|
|
92
93
|
function setData(newData, oldData, changedKeys2, excludes) {
|
|
93
94
|
let changed = false;
|
|
94
95
|
for (const p in newData) {
|
|
95
|
-
if (
|
|
96
|
+
if (hasOwnProperty(newData, p)) {
|
|
96
97
|
const now2 = newData[p];
|
|
97
98
|
const old = oldData[p];
|
|
98
99
|
if ((!isPrimitiveOrFunc(now2) || old !== now2) && !excludes.has(p)) {
|
|
99
|
-
changedKeys2
|
|
100
|
+
changedKeys2.add(p);
|
|
100
101
|
changed = true;
|
|
101
102
|
}
|
|
102
103
|
oldData[p] = now2;
|
|
@@ -104,17 +105,25 @@ function setData(newData, oldData, changedKeys2, excludes) {
|
|
|
104
105
|
}
|
|
105
106
|
return changed;
|
|
106
107
|
}
|
|
108
|
+
function isRefToken(s) {
|
|
109
|
+
if (s.length < 2 || s[0] !== SPLITTER) return false;
|
|
110
|
+
for (let i = 1; i < s.length; i++) {
|
|
111
|
+
const c = s.charCodeAt(i);
|
|
112
|
+
if (c < 48 || c > 57) return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
107
116
|
function translateData(data, value) {
|
|
108
117
|
if (isPrimitive(value)) {
|
|
109
118
|
const prop = String(value);
|
|
110
|
-
if (prop
|
|
119
|
+
if (isRefToken(prop) && hasOwnProperty(data, prop)) {
|
|
111
120
|
return data[prop];
|
|
112
121
|
}
|
|
113
122
|
return value;
|
|
114
123
|
}
|
|
115
124
|
if (isPlainObject(value) || Array.isArray(value)) {
|
|
116
125
|
for (const p in value) {
|
|
117
|
-
if (
|
|
126
|
+
if (hasOwnProperty(value, p)) {
|
|
118
127
|
const val = value[p];
|
|
119
128
|
const newVal = translateData(data, val);
|
|
120
129
|
value[p] = newVal;
|
|
@@ -151,38 +160,33 @@ function nodeInside(a, b) {
|
|
|
151
160
|
return false;
|
|
152
161
|
}
|
|
153
162
|
}
|
|
154
|
-
var paramsTemp = {};
|
|
155
|
-
function paramsReplacer(_match, name, value) {
|
|
156
|
-
try {
|
|
157
|
-
paramsTemp[name] = decodeURIComponent(value || "");
|
|
158
|
-
} catch {
|
|
159
|
-
paramsTemp[name] = value || "";
|
|
160
|
-
}
|
|
161
|
-
return "";
|
|
162
|
-
}
|
|
163
163
|
function parseUri(uri) {
|
|
164
|
-
|
|
164
|
+
const params = {};
|
|
165
165
|
const path = uri.replace(URL_QUERY_HASH_REGEXP, "");
|
|
166
166
|
const pathname = path;
|
|
167
167
|
const actualPath = uri === pathname && IS_URL_PARAMS.test(pathname) ? "" : pathname;
|
|
168
|
-
uri.replace(actualPath, "").replace(URL_PARAM_REGEXP,
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
168
|
+
uri.replace(actualPath, "").replace(URL_PARAM_REGEXP, (_match, name, value) => {
|
|
169
|
+
try {
|
|
170
|
+
params[name] = decodeURIComponent(value || "");
|
|
171
|
+
} catch {
|
|
172
|
+
params[name] = value || "";
|
|
173
|
+
}
|
|
174
|
+
return "";
|
|
175
|
+
});
|
|
176
|
+
return { path: actualPath, params };
|
|
173
177
|
}
|
|
174
178
|
var IS_URL_PARAMS = {
|
|
175
179
|
test(s) {
|
|
176
180
|
return /(?!^)=|&/.test(s);
|
|
177
181
|
}
|
|
178
182
|
};
|
|
179
|
-
function toUri(path, params,
|
|
183
|
+
function toUri(path, params, keepEmpty) {
|
|
180
184
|
const pairs = [];
|
|
181
185
|
let hasParams = false;
|
|
182
186
|
for (const p in params) {
|
|
183
|
-
if (
|
|
187
|
+
if (hasOwnProperty(params, p)) {
|
|
184
188
|
const v = String(params[p] ?? "");
|
|
185
|
-
if (!
|
|
189
|
+
if (!keepEmpty || v || keepEmpty.has(p)) {
|
|
186
190
|
pairs.push(`${p}=${encodeURIComponent(v)}`);
|
|
187
191
|
hasParams = true;
|
|
188
192
|
}
|
|
@@ -205,14 +209,6 @@ function toMap(list, key) {
|
|
|
205
209
|
function now() {
|
|
206
210
|
return Date.now ? Date.now() : (/* @__PURE__ */ new Date()).getTime();
|
|
207
211
|
}
|
|
208
|
-
function classExtend(make, base, props, statics) {
|
|
209
|
-
const baseProto = base["prototype"] ?? {};
|
|
210
|
-
const classProto = Object.create(baseProto);
|
|
211
|
-
assign(classProto, props);
|
|
212
|
-
Object.assign(make, statics);
|
|
213
|
-
classProto.constructor = make;
|
|
214
|
-
make["prototype"] = classProto;
|
|
215
|
-
}
|
|
216
212
|
|
|
217
213
|
// src/apply-style.ts
|
|
218
214
|
var injectedStyleIds = /* @__PURE__ */ new Set();
|
|
@@ -252,27 +248,35 @@ function applyStyle(styleIdOrPairs, css) {
|
|
|
252
248
|
}
|
|
253
249
|
|
|
254
250
|
// src/mark.ts
|
|
255
|
-
var
|
|
256
|
-
|
|
251
|
+
var hostStore = /* @__PURE__ */ new WeakMap();
|
|
252
|
+
function getOrCreate(host) {
|
|
253
|
+
let record = hostStore.get(host);
|
|
254
|
+
if (!record) {
|
|
255
|
+
record = { signs: /* @__PURE__ */ new Map(), deleted: false };
|
|
256
|
+
hostStore.set(host, record);
|
|
257
|
+
}
|
|
258
|
+
return record;
|
|
259
|
+
}
|
|
257
260
|
function mark(host, key) {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const markHost = hostRecord[MARK_OBJECT_KEY] || (hostRecord[MARK_OBJECT_KEY] = {});
|
|
262
|
-
if (!Object.prototype.hasOwnProperty.call(markHost, key)) {
|
|
263
|
-
markHost[key] = 0;
|
|
264
|
-
}
|
|
265
|
-
sign = ++markHost[key];
|
|
261
|
+
const record = getOrCreate(host);
|
|
262
|
+
if (record.deleted) {
|
|
263
|
+
return () => false;
|
|
266
264
|
}
|
|
265
|
+
const sign = (record.signs.get(key) ?? 0) + 1;
|
|
266
|
+
record.signs.set(key, sign);
|
|
267
267
|
return () => {
|
|
268
|
-
const
|
|
269
|
-
return !!
|
|
268
|
+
const current = hostStore.get(host);
|
|
269
|
+
return !!current && !current.deleted && current.signs.get(key) === sign;
|
|
270
270
|
};
|
|
271
271
|
}
|
|
272
272
|
function unmark(host) {
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
const record = hostStore.get(host);
|
|
274
|
+
if (record) {
|
|
275
|
+
record.deleted = true;
|
|
276
|
+
record.signs.clear();
|
|
277
|
+
} else {
|
|
278
|
+
hostStore.set(host, { signs: /* @__PURE__ */ new Map(), deleted: true });
|
|
279
|
+
}
|
|
276
280
|
}
|
|
277
281
|
|
|
278
282
|
// src/safeguard.ts
|
|
@@ -318,7 +322,7 @@ function safeguard(data, getter, setter, isRoot) {
|
|
|
318
322
|
if (!prefix && getter) {
|
|
319
323
|
getter(property);
|
|
320
324
|
}
|
|
321
|
-
if (!isRoot &&
|
|
325
|
+
if (!isRoot && hasOwnProperty(target, property) && (Array.isArray(out) || isPlainObject(out))) {
|
|
322
326
|
return build(prefix + property + ".", out);
|
|
323
327
|
}
|
|
324
328
|
return out;
|
|
@@ -407,15 +411,17 @@ var Cache = class {
|
|
|
407
411
|
this.lookup.set(prefixedKey, entry);
|
|
408
412
|
}
|
|
409
413
|
/**
|
|
410
|
-
* Delete a cached entry.
|
|
414
|
+
* Delete a cached entry. Removes it immediately from both the lookup map
|
|
415
|
+
* and the entries array so the GC can reclaim the value without waiting
|
|
416
|
+
* for the next eviction sweep.
|
|
411
417
|
*/
|
|
412
418
|
del(key) {
|
|
413
419
|
const prefixedKey = this.prefixKey(key);
|
|
414
420
|
const entry = this.lookup.get(prefixedKey);
|
|
415
421
|
if (!entry) return;
|
|
416
|
-
entry.frequency = -1;
|
|
417
|
-
entry.value = void 0;
|
|
418
422
|
this.lookup.delete(prefixedKey);
|
|
423
|
+
const idx = this.entries.indexOf(entry);
|
|
424
|
+
if (idx !== -1) this.entries.splice(idx, 1);
|
|
419
425
|
if (this.onRemove) {
|
|
420
426
|
this.onRemove(key);
|
|
421
427
|
}
|
|
@@ -440,20 +446,46 @@ var Cache = class {
|
|
|
440
446
|
this.entries = [];
|
|
441
447
|
this.lookup.clear();
|
|
442
448
|
}
|
|
443
|
-
/**
|
|
449
|
+
/**
|
|
450
|
+
* Evict the `bufferSize` worst entries from the cache.
|
|
451
|
+
*
|
|
452
|
+
* Uses single-pass partial selection (O(n·k)) instead of sorting the entire
|
|
453
|
+
* `entries` array (O(n log n)). For the typical `bufferSize = 5` this is
|
|
454
|
+
* effectively a linear scan with at most 5 in-bucket comparisons per
|
|
455
|
+
* iteration — and it avoids mutating the rest of `entries`.
|
|
456
|
+
*/
|
|
444
457
|
evictEntries() {
|
|
445
|
-
this.entries
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
this.lookup.delete(this.prefixKey(
|
|
451
|
-
if (this.onRemove)
|
|
452
|
-
this.onRemove(entry.originalKey);
|
|
453
|
-
}
|
|
458
|
+
const entries = this.entries;
|
|
459
|
+
const k = this.bufferSize;
|
|
460
|
+
if (k <= 0 || entries.length === 0) return;
|
|
461
|
+
if (entries.length <= k) {
|
|
462
|
+
for (const e of entries) {
|
|
463
|
+
this.lookup.delete(this.prefixKey(e.originalKey));
|
|
464
|
+
if (this.onRemove) this.onRemove(e.originalKey);
|
|
454
465
|
}
|
|
466
|
+
this.entries = [];
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
const cmp = this.comparator;
|
|
470
|
+
const worst = [];
|
|
471
|
+
for (const entry of entries) {
|
|
472
|
+
if (worst.length < k) {
|
|
473
|
+
let i = worst.length;
|
|
474
|
+
while (i > 0 && cmp(entry, worst[i - 1]) > 0) i--;
|
|
475
|
+
worst.splice(i, 0, entry);
|
|
476
|
+
} else if (cmp(entry, worst[k - 1]) > 0) {
|
|
477
|
+
worst.pop();
|
|
478
|
+
let i = worst.length;
|
|
479
|
+
while (i > 0 && cmp(entry, worst[i - 1]) > 0) i--;
|
|
480
|
+
worst.splice(i, 0, entry);
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
const evictSet = new Set(worst);
|
|
484
|
+
for (const e of worst) {
|
|
485
|
+
this.lookup.delete(this.prefixKey(e.originalKey));
|
|
486
|
+
if (this.onRemove) this.onRemove(e.originalKey);
|
|
455
487
|
}
|
|
456
|
-
this.entries =
|
|
488
|
+
this.entries = entries.filter((e) => !evictSet.has(e));
|
|
457
489
|
}
|
|
458
490
|
};
|
|
459
491
|
|
|
@@ -461,6 +493,10 @@ var Cache = class {
|
|
|
461
493
|
var EventEmitter = class {
|
|
462
494
|
/** Event listeners: prefixed key -> listener array */
|
|
463
495
|
listeners = /* @__PURE__ */ new Map();
|
|
496
|
+
/** Number of `fire()` calls currently on the stack (re-entrancy depth). */
|
|
497
|
+
firingDepth = 0;
|
|
498
|
+
/** Keys whose listener list needs compaction after firing settles. */
|
|
499
|
+
pendingCompaction;
|
|
464
500
|
/**
|
|
465
501
|
* Bind event listener.
|
|
466
502
|
*/
|
|
@@ -483,13 +519,23 @@ var EventEmitter = class {
|
|
|
483
519
|
const key = SPLITTER + event;
|
|
484
520
|
if (handler) {
|
|
485
521
|
const list = this.listeners.get(key);
|
|
486
|
-
if (list)
|
|
522
|
+
if (!list) return this;
|
|
523
|
+
if (this.firingDepth > 0) {
|
|
487
524
|
for (const listener of list) {
|
|
488
525
|
if (listener.handler === handler) {
|
|
489
526
|
listener.handler = noop;
|
|
527
|
+
(this.pendingCompaction ??= /* @__PURE__ */ new Set()).add(key);
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
} else {
|
|
532
|
+
for (let i = 0; i < list.length; i++) {
|
|
533
|
+
if (list[i].handler === handler) {
|
|
534
|
+
list.splice(i, 1);
|
|
490
535
|
break;
|
|
491
536
|
}
|
|
492
537
|
}
|
|
538
|
+
if (list.length === 0) this.listeners.delete(key);
|
|
493
539
|
}
|
|
494
540
|
} else {
|
|
495
541
|
this.listeners.delete(key);
|
|
@@ -501,9 +547,9 @@ var EventEmitter = class {
|
|
|
501
547
|
return this;
|
|
502
548
|
}
|
|
503
549
|
/**
|
|
504
|
-
* Fire event, execute all bound handlers.
|
|
505
|
-
*
|
|
506
|
-
*
|
|
550
|
+
* Fire event, execute all bound handlers. Safe for re-entrant `off()` calls
|
|
551
|
+
* during dispatch: removed handlers are replaced with noop and compacted
|
|
552
|
+
* after the outermost fire returns.
|
|
507
553
|
*
|
|
508
554
|
* @param event - Event name
|
|
509
555
|
* @param data - Event data (type property added automatically)
|
|
@@ -517,38 +563,41 @@ var EventEmitter = class {
|
|
|
517
563
|
data = {};
|
|
518
564
|
}
|
|
519
565
|
data["type"] = event;
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
566
|
+
this.firingDepth++;
|
|
567
|
+
try {
|
|
568
|
+
if (list) {
|
|
569
|
+
const len = list.length;
|
|
570
|
+
for (let i = 0; i < len; i++) {
|
|
571
|
+
const idx = lastToFirst ? len - 1 - i : i;
|
|
572
|
+
const listener = list[idx];
|
|
573
|
+
if (!listener) continue;
|
|
574
|
+
if (listener.handler === noop) continue;
|
|
527
575
|
listener.executing = 1;
|
|
528
|
-
funcWithTry(
|
|
529
|
-
[listener.handler],
|
|
530
|
-
[data],
|
|
531
|
-
this,
|
|
532
|
-
noop
|
|
533
|
-
);
|
|
576
|
+
funcWithTry([listener.handler], [data], this, noop);
|
|
534
577
|
listener.executing = "";
|
|
535
|
-
} else if (!listener.executing) {
|
|
536
|
-
list.splice(idx, 1);
|
|
537
578
|
}
|
|
538
579
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
580
|
+
const onMethodName = `on${event[0].toUpperCase() + event.slice(1)}`;
|
|
581
|
+
const onMethod = this[onMethodName];
|
|
582
|
+
if (typeof onMethod === "function") {
|
|
583
|
+
funcWithTry([onMethod], [data], this, noop);
|
|
584
|
+
}
|
|
585
|
+
if (remove) {
|
|
586
|
+
this.off(event);
|
|
587
|
+
}
|
|
588
|
+
} finally {
|
|
589
|
+
this.firingDepth--;
|
|
590
|
+
if (this.firingDepth === 0 && this.pendingCompaction) {
|
|
591
|
+
for (const k of this.pendingCompaction) {
|
|
592
|
+
const l = this.listeners.get(k);
|
|
593
|
+
if (!l) continue;
|
|
594
|
+
for (let i = l.length - 1; i >= 0; i--) {
|
|
595
|
+
if (l[i].handler === noop) l.splice(i, 1);
|
|
596
|
+
}
|
|
597
|
+
if (l.length === 0) this.listeners.delete(k);
|
|
598
|
+
}
|
|
599
|
+
this.pendingCompaction = void 0;
|
|
600
|
+
}
|
|
552
601
|
}
|
|
553
602
|
return this;
|
|
554
603
|
}
|
|
@@ -557,8 +606,8 @@ var EventEmitter = class {
|
|
|
557
606
|
// src/state.ts
|
|
558
607
|
var appData = {};
|
|
559
608
|
var keyRefCounts = {};
|
|
560
|
-
var changedKeys =
|
|
561
|
-
var stashedChangedKeys =
|
|
609
|
+
var changedKeys = /* @__PURE__ */ new Set();
|
|
610
|
+
var stashedChangedKeys = EMPTY_STRING_SET;
|
|
562
611
|
var dataIsChanged = false;
|
|
563
612
|
var dataWhereSet = {};
|
|
564
613
|
var emitter = new EventEmitter();
|
|
@@ -569,7 +618,7 @@ function markBooted() {
|
|
|
569
618
|
function setupKeysRef(keys2) {
|
|
570
619
|
const keyList = keys2.split(",");
|
|
571
620
|
for (const key of keyList) {
|
|
572
|
-
if (
|
|
621
|
+
if (hasOwnProperty(keyRefCounts, key)) {
|
|
573
622
|
keyRefCounts[key]++;
|
|
574
623
|
} else {
|
|
575
624
|
keyRefCounts[key] = 1;
|
|
@@ -579,7 +628,7 @@ function setupKeysRef(keys2) {
|
|
|
579
628
|
}
|
|
580
629
|
function teardownKeysRef(keyList) {
|
|
581
630
|
for (const key of keyList) {
|
|
582
|
-
if (
|
|
631
|
+
if (hasOwnProperty(keyRefCounts, key)) {
|
|
583
632
|
const count = --keyRefCounts[key];
|
|
584
633
|
if (count <= 0) {
|
|
585
634
|
Reflect.deleteProperty(keyRefCounts, key);
|
|
@@ -591,35 +640,14 @@ function teardownKeysRef(keyList) {
|
|
|
591
640
|
}
|
|
592
641
|
}
|
|
593
642
|
}
|
|
594
|
-
var
|
|
595
|
-
var notifyList = [];
|
|
596
|
-
var notifyTimer;
|
|
643
|
+
var warnedKeys = /* @__PURE__ */ new Set();
|
|
597
644
|
function clearNotify(key) {
|
|
598
|
-
|
|
599
|
-
if (notifyList[i]?.key === key) {
|
|
600
|
-
notifyList.splice(i, 1);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
function doNotify() {
|
|
605
|
-
const locker = {};
|
|
606
|
-
for (const n of notifyList) {
|
|
607
|
-
if (!locker[n.key]) {
|
|
608
|
-
console.warn(n.message);
|
|
609
|
-
locker[n.key] = 1;
|
|
610
|
-
}
|
|
611
|
-
}
|
|
612
|
-
notifyList.length = 0;
|
|
613
|
-
notifyStarted = 0;
|
|
645
|
+
warnedKeys.delete(key);
|
|
614
646
|
}
|
|
615
647
|
function delayNotify(key, message) {
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
if (!notifyStarted) {
|
|
620
|
-
notifyStarted = 1;
|
|
621
|
-
notifyTimer = setTimeout(doNotify, 500);
|
|
622
|
-
}
|
|
648
|
+
if (warnedKeys.has(key)) return;
|
|
649
|
+
warnedKeys.add(key);
|
|
650
|
+
console.warn(message);
|
|
623
651
|
}
|
|
624
652
|
var State = {
|
|
625
653
|
/**
|
|
@@ -631,7 +659,7 @@ var State = {
|
|
|
631
659
|
return safeguard(
|
|
632
660
|
result,
|
|
633
661
|
(dataKey) => {
|
|
634
|
-
if (booted &&
|
|
662
|
+
if (booted && hasOwnProperty(dataWhereSet, dataKey) && dataWhereSet[dataKey] !== window.location.pathname) {
|
|
635
663
|
console.warn(
|
|
636
664
|
`beware! You get state:"{State}.${dataKey}" where it set by page:${dataWhereSet[dataKey]}`
|
|
637
665
|
);
|
|
@@ -652,7 +680,7 @@ var State = {
|
|
|
652
680
|
* Set data to state.
|
|
653
681
|
*/
|
|
654
682
|
set(data, excludes) {
|
|
655
|
-
dataIsChanged = setData(data, appData, changedKeys, excludes ||
|
|
683
|
+
dataIsChanged = setData(data, appData, changedKeys, excludes || EMPTY_STRING_SET) || dataIsChanged;
|
|
656
684
|
if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && booted) {
|
|
657
685
|
for (const p in data) {
|
|
658
686
|
dataWhereSet[p] = window.location.pathname;
|
|
@@ -669,26 +697,19 @@ var State = {
|
|
|
669
697
|
}
|
|
670
698
|
if (dataIsChanged) {
|
|
671
699
|
if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
|
|
672
|
-
for (const p
|
|
673
|
-
|
|
674
|
-
clearNotify(p);
|
|
675
|
-
}
|
|
700
|
+
for (const p of changedKeys) {
|
|
701
|
+
clearNotify(p);
|
|
676
702
|
}
|
|
677
703
|
}
|
|
678
704
|
dataIsChanged = false;
|
|
679
|
-
const keys2 =
|
|
680
|
-
for (const k in changedKeys) {
|
|
681
|
-
if (has(changedKeys, k)) {
|
|
682
|
-
keys2[k] = 1;
|
|
683
|
-
}
|
|
684
|
-
}
|
|
705
|
+
const keys2 = changedKeys;
|
|
685
706
|
stashedChangedKeys = keys2;
|
|
686
|
-
changedKeys =
|
|
687
|
-
emitter.fire(
|
|
707
|
+
changedKeys = /* @__PURE__ */ new Set();
|
|
708
|
+
emitter.fire(RouterEvents.CHANGED, { keys: keys2 });
|
|
688
709
|
}
|
|
689
710
|
},
|
|
690
711
|
/**
|
|
691
|
-
* Get
|
|
712
|
+
* Get the set of keys changed in the most recent digest.
|
|
692
713
|
*/
|
|
693
714
|
diff() {
|
|
694
715
|
return stashedChangedKeys;
|
|
@@ -746,6 +767,7 @@ var cachedDefaultPath;
|
|
|
746
767
|
var cachedRewrite;
|
|
747
768
|
var defaultTitle;
|
|
748
769
|
var frameworkConfig;
|
|
770
|
+
var beforeEachGuards = [];
|
|
749
771
|
function createEmptyLocation() {
|
|
750
772
|
return {
|
|
751
773
|
href: "",
|
|
@@ -900,7 +922,7 @@ var Router = {
|
|
|
900
922
|
document.title = defaultTitle || document.title;
|
|
901
923
|
}
|
|
902
924
|
emitter2.fire(
|
|
903
|
-
|
|
925
|
+
RouterEvents.CHANGED,
|
|
904
926
|
lastChanged
|
|
905
927
|
);
|
|
906
928
|
}
|
|
@@ -933,16 +955,16 @@ var Router = {
|
|
|
933
955
|
}
|
|
934
956
|
const lPath = lastLocation["path"] || "";
|
|
935
957
|
const lParams = lastLocation["params"];
|
|
936
|
-
const lQuery =
|
|
958
|
+
const lQuery = /* @__PURE__ */ new Set();
|
|
937
959
|
for (const k in lastLocation.query["params"]) {
|
|
938
|
-
if (
|
|
939
|
-
lQuery
|
|
960
|
+
if (hasOwnProperty(lastLocation.query["params"], k)) {
|
|
961
|
+
lQuery.add(k);
|
|
940
962
|
}
|
|
941
963
|
}
|
|
942
964
|
if (tPath) {
|
|
943
|
-
if (!
|
|
944
|
-
for (const qKey
|
|
945
|
-
if (
|
|
965
|
+
if (!hasOwnProperty(window, "history")) {
|
|
966
|
+
for (const qKey of lQuery) {
|
|
967
|
+
if (!hasOwnProperty(tParams, qKey)) {
|
|
946
968
|
tParams[qKey] = "";
|
|
947
969
|
}
|
|
948
970
|
}
|
|
@@ -951,14 +973,17 @@ var Router = {
|
|
|
951
973
|
tPath = lPath;
|
|
952
974
|
tParams = assign({}, lParams, tParams);
|
|
953
975
|
}
|
|
954
|
-
updateUrl(
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
)
|
|
976
|
+
updateUrl(tPath, tParams, lastLocation, replace, silentFlag, lQuery);
|
|
977
|
+
},
|
|
978
|
+
/**
|
|
979
|
+
* Register an async-friendly navigation guard. See `RouterInterface.beforeEach`.
|
|
980
|
+
*/
|
|
981
|
+
beforeEach(guard) {
|
|
982
|
+
beforeEachGuards.push(guard);
|
|
983
|
+
return () => {
|
|
984
|
+
const idx = beforeEachGuards.indexOf(guard);
|
|
985
|
+
if (idx !== -1) beforeEachGuards.splice(idx, 1);
|
|
986
|
+
};
|
|
962
987
|
},
|
|
963
988
|
/**
|
|
964
989
|
* Join multiple path segments into a single path.
|
|
@@ -1022,12 +1047,39 @@ var Router = {
|
|
|
1022
1047
|
}
|
|
1023
1048
|
};
|
|
1024
1049
|
Router.fire(
|
|
1025
|
-
|
|
1050
|
+
RouterEvents.CHANGE,
|
|
1026
1051
|
changeEvent
|
|
1027
1052
|
);
|
|
1028
|
-
if (
|
|
1053
|
+
if (suspend || changeEvent.p) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (beforeEachGuards.length === 0) {
|
|
1029
1057
|
changeEvent.resolve();
|
|
1058
|
+
return;
|
|
1030
1059
|
}
|
|
1060
|
+
const from = lastLocation;
|
|
1061
|
+
const to = loc;
|
|
1062
|
+
const guards = beforeEachGuards.slice();
|
|
1063
|
+
let chain = Promise.resolve(true);
|
|
1064
|
+
for (const guard of guards) {
|
|
1065
|
+
chain = chain.then((prev) => {
|
|
1066
|
+
if (prev === false) return false;
|
|
1067
|
+
return guard(to, from);
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
chain.then(
|
|
1071
|
+
(result) => {
|
|
1072
|
+
if (changeEvent.p) return;
|
|
1073
|
+
if (result === false) {
|
|
1074
|
+
changeEvent.reject();
|
|
1075
|
+
} else {
|
|
1076
|
+
changeEvent.resolve();
|
|
1077
|
+
}
|
|
1078
|
+
},
|
|
1079
|
+
() => {
|
|
1080
|
+
if (!changeEvent.p) changeEvent.reject();
|
|
1081
|
+
}
|
|
1082
|
+
);
|
|
1031
1083
|
}
|
|
1032
1084
|
};
|
|
1033
1085
|
Router.notify = watchChange;
|
|
@@ -1035,7 +1087,7 @@ var Router = {
|
|
|
1035
1087
|
window.addEventListener("popstate", watchChange);
|
|
1036
1088
|
window.addEventListener("beforeunload", (domEvent) => {
|
|
1037
1089
|
const data = {};
|
|
1038
|
-
Router.fire(
|
|
1090
|
+
Router.fire(RouterEvents.PAGE_UNLOAD, data);
|
|
1039
1091
|
const msg = data["msg"];
|
|
1040
1092
|
if (msg) {
|
|
1041
1093
|
domEvent.returnValue = msg;
|
|
@@ -1081,13 +1133,17 @@ function parseEventInfo(eventInfo) {
|
|
|
1081
1133
|
}
|
|
1082
1134
|
function findFrameInfo(current, eventType) {
|
|
1083
1135
|
const eventInfos = [];
|
|
1084
|
-
let begin = current;
|
|
1085
1136
|
const info = current.getAttribute(`@${eventType}`);
|
|
1137
|
+
const hasSelectorEvents = !!selectorEvents[eventType];
|
|
1138
|
+
if (!info && !hasSelectorEvents) {
|
|
1139
|
+
return eventInfos;
|
|
1140
|
+
}
|
|
1141
|
+
let begin = current;
|
|
1086
1142
|
let match;
|
|
1087
1143
|
if (info) {
|
|
1088
1144
|
match = parseEventInfo(info);
|
|
1089
1145
|
}
|
|
1090
|
-
if (match && !match.id ||
|
|
1146
|
+
if (match && !match.id || hasSelectorEvents) {
|
|
1091
1147
|
let selectorFrameId = "#";
|
|
1092
1148
|
let backtrace = 0;
|
|
1093
1149
|
while (begin && begin !== document.body) {
|
|
@@ -1260,7 +1316,7 @@ var EventDelegator = {
|
|
|
1260
1316
|
};
|
|
1261
1317
|
|
|
1262
1318
|
// src/vdom.ts
|
|
1263
|
-
var
|
|
1319
|
+
var wrapMeta = {
|
|
1264
1320
|
option: [1, "<select multiple>"],
|
|
1265
1321
|
thead: [1, "<table>"],
|
|
1266
1322
|
col: [2, "<table><colgroup>"],
|
|
@@ -1272,9 +1328,9 @@ var WrapMeta = {
|
|
|
1272
1328
|
math: [1, '<math xmlns="' + MATH_NS + '">'],
|
|
1273
1329
|
_: [0, ""]
|
|
1274
1330
|
};
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1331
|
+
wrapMeta["optgroup"] = wrapMeta["option"];
|
|
1332
|
+
wrapMeta["tbody"] = wrapMeta["tfoot"] = wrapMeta["colgroup"] = wrapMeta["caption"] = wrapMeta["thead"];
|
|
1333
|
+
wrapMeta["th"] = wrapMeta["td"];
|
|
1278
1334
|
var VDoc = document.implementation.createHTMLDocument("");
|
|
1279
1335
|
var VBase = VDoc.createElement("base");
|
|
1280
1336
|
VBase.href = document.location.href;
|
|
@@ -1285,16 +1341,12 @@ var VDomSpecials = {
|
|
|
1285
1341
|
OPTION: ["selected"]
|
|
1286
1342
|
};
|
|
1287
1343
|
function vdomUnmountFrames(frame, node) {
|
|
1288
|
-
if (node
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (children.includes(id)) {
|
|
1295
|
-
frame.unmountFrame(id);
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1344
|
+
if (!(node instanceof Element)) return;
|
|
1345
|
+
const id = node.getAttribute("id");
|
|
1346
|
+
if (!id) return;
|
|
1347
|
+
frame.unmountZone(id);
|
|
1348
|
+
if (frame.children().includes(id)) {
|
|
1349
|
+
frame.unmountFrame(id);
|
|
1298
1350
|
}
|
|
1299
1351
|
}
|
|
1300
1352
|
function vdomGetNode(html, refNode) {
|
|
@@ -1309,7 +1361,7 @@ function vdomGetNode(html, refNode) {
|
|
|
1309
1361
|
const match = TAG_NAME_REGEXP.exec(html);
|
|
1310
1362
|
tag = match ? match[1] : "";
|
|
1311
1363
|
}
|
|
1312
|
-
const wrap =
|
|
1364
|
+
const wrap = wrapMeta[tag] || wrapMeta["_"];
|
|
1313
1365
|
tmp.innerHTML = wrap[1] + html;
|
|
1314
1366
|
let j = wrap[0];
|
|
1315
1367
|
while (j--) {
|
|
@@ -1326,7 +1378,7 @@ function vdomGetCompareKey(node) {
|
|
|
1326
1378
|
}
|
|
1327
1379
|
let key = el.autoId ? "" : el.getAttribute("id") || void 0;
|
|
1328
1380
|
if (!key) {
|
|
1329
|
-
key = el.getAttribute(
|
|
1381
|
+
key = el.getAttribute(LarkInnerKeys.DIFF_KEY) || void 0;
|
|
1330
1382
|
}
|
|
1331
1383
|
if (!key) {
|
|
1332
1384
|
const larkView = el.getAttribute(LARK_VIEW);
|
|
@@ -1339,8 +1391,7 @@ function vdomGetCompareKey(node) {
|
|
|
1339
1391
|
return key;
|
|
1340
1392
|
}
|
|
1341
1393
|
function vdomSpecialDiff(oldNode, newNode) {
|
|
1342
|
-
const
|
|
1343
|
-
const specials = VDomSpecials[nodeName];
|
|
1394
|
+
const specials = VDomSpecials[oldNode.nodeName];
|
|
1344
1395
|
if (!specials) return 0;
|
|
1345
1396
|
const oldEl = oldNode;
|
|
1346
1397
|
const newEl = newNode;
|
|
@@ -1389,13 +1440,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1389
1440
|
let oldNode = oldParent.lastChild;
|
|
1390
1441
|
let newNode = newParent.firstChild;
|
|
1391
1442
|
let extra = 0;
|
|
1392
|
-
const keyedNodes =
|
|
1393
|
-
const newKeyedNodes =
|
|
1443
|
+
const keyedNodes = /* @__PURE__ */ new Map();
|
|
1444
|
+
const newKeyedNodes = /* @__PURE__ */ new Map();
|
|
1394
1445
|
while (oldNode) {
|
|
1395
1446
|
extra++;
|
|
1396
1447
|
const nodeKey = vdomGetCompareKey(oldNode);
|
|
1397
1448
|
if (nodeKey) {
|
|
1398
|
-
|
|
1449
|
+
let bucket = keyedNodes.get(nodeKey);
|
|
1450
|
+
if (!bucket) {
|
|
1451
|
+
bucket = [];
|
|
1452
|
+
keyedNodes.set(nodeKey, bucket);
|
|
1453
|
+
}
|
|
1399
1454
|
bucket.push(oldNode);
|
|
1400
1455
|
}
|
|
1401
1456
|
oldNode = oldNode.previousSibling;
|
|
@@ -1403,7 +1458,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1403
1458
|
while (newNode) {
|
|
1404
1459
|
const nodeKey = vdomGetCompareKey(newNode);
|
|
1405
1460
|
if (nodeKey) {
|
|
1406
|
-
newKeyedNodes
|
|
1461
|
+
newKeyedNodes.set(nodeKey, (newKeyedNodes.get(nodeKey) ?? 0) + 1);
|
|
1407
1462
|
}
|
|
1408
1463
|
newNode = newNode.nextSibling;
|
|
1409
1464
|
}
|
|
@@ -1414,23 +1469,25 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1414
1469
|
const tempNew = newNode;
|
|
1415
1470
|
newNode = newNode.nextSibling;
|
|
1416
1471
|
const nodeKey = vdomGetCompareKey(tempNew);
|
|
1417
|
-
let foundNode = nodeKey ? keyedNodes
|
|
1472
|
+
let foundNode = nodeKey ? keyedNodes.get(nodeKey) : void 0;
|
|
1418
1473
|
if (foundNode && (foundNode = foundNode.slice()) && foundNode.length) {
|
|
1419
1474
|
const matched = foundNode.pop();
|
|
1420
1475
|
while (matched !== oldNode) {
|
|
1421
|
-
|
|
1476
|
+
if (!oldNode) break;
|
|
1477
|
+
const next = oldNode.nextSibling;
|
|
1422
1478
|
oldParent.appendChild(oldNode);
|
|
1423
1479
|
oldNode = next;
|
|
1424
1480
|
}
|
|
1425
1481
|
oldNode = matched.nextSibling;
|
|
1426
|
-
if (nodeKey
|
|
1427
|
-
newKeyedNodes
|
|
1482
|
+
if (nodeKey) {
|
|
1483
|
+
const c = newKeyedNodes.get(nodeKey);
|
|
1484
|
+
if (c) newKeyedNodes.set(nodeKey, c - 1);
|
|
1428
1485
|
}
|
|
1429
1486
|
vdomSetNode(matched, tempNew, oldParent, ref, frame, keys_);
|
|
1430
1487
|
} else if (oldNode) {
|
|
1431
1488
|
const tempOld2 = oldNode;
|
|
1432
1489
|
const oldKey = vdomGetCompareKey(tempOld2);
|
|
1433
|
-
if (oldKey && keyedNodes
|
|
1490
|
+
if (oldKey && keyedNodes.has(oldKey) && newKeyedNodes.get(oldKey)) {
|
|
1434
1491
|
extra++;
|
|
1435
1492
|
ref.hasChanged = 1;
|
|
1436
1493
|
ref.domOps.push([8, oldParent, tempNew, tempOld2]);
|
|
@@ -1454,17 +1511,21 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1454
1511
|
}
|
|
1455
1512
|
}
|
|
1456
1513
|
function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
|
|
1457
|
-
|
|
1514
|
+
const oldAsEl = oldNode instanceof Element ? oldNode : null;
|
|
1515
|
+
const newAsEl = newNode instanceof Element ? newNode : null;
|
|
1516
|
+
const hasViewKey = !!oldAsEl?.hasAttribute(LarkInnerKeys.VIEW_KEY);
|
|
1517
|
+
const equalAsNodes = oldAsEl !== null && newAsEl !== null && oldAsEl.isEqualNode && oldAsEl.isEqualNode(newAsEl);
|
|
1518
|
+
if (vdomSpecialDiff(oldNode, newNode) || hasViewKey || !equalAsNodes) {
|
|
1458
1519
|
if (oldNode.nodeType === newNode.nodeType && oldNode.nodeName === newNode.nodeName) {
|
|
1459
|
-
if (
|
|
1460
|
-
const oldEl =
|
|
1461
|
-
const newEl =
|
|
1462
|
-
const staticKey = newEl.getAttribute(
|
|
1463
|
-
if (staticKey && staticKey === oldEl.getAttribute(
|
|
1520
|
+
if (oldAsEl !== null && newAsEl !== null) {
|
|
1521
|
+
const oldEl = oldAsEl;
|
|
1522
|
+
const newEl = newAsEl;
|
|
1523
|
+
const staticKey = newEl.getAttribute(LarkInnerKeys.DIFF_KEY);
|
|
1524
|
+
if (staticKey && staticKey === oldEl.getAttribute(LarkInnerKeys.DIFF_KEY)) {
|
|
1464
1525
|
return;
|
|
1465
1526
|
}
|
|
1466
1527
|
const newLarkView = newEl.getAttribute(LARK_VIEW);
|
|
1467
|
-
const updateAttribute = !newEl.getAttribute(
|
|
1528
|
+
const updateAttribute = !newEl.getAttribute(LarkInnerKeys.ATTR_KEY) || newEl.getAttribute(LarkInnerKeys.ATTR_KEY) !== oldEl.getAttribute(LarkInnerKeys.ATTR_KEY);
|
|
1468
1529
|
let updateChildren = true;
|
|
1469
1530
|
if (newLarkView) {
|
|
1470
1531
|
const oldFrameId = oldEl.getAttribute("id") || "";
|
|
@@ -1565,7 +1626,8 @@ function encodeQ(v) {
|
|
|
1565
1626
|
}
|
|
1566
1627
|
|
|
1567
1628
|
// src/updater.ts
|
|
1568
|
-
function updaterRef(
|
|
1629
|
+
function updaterRef(refDataIn, value, key) {
|
|
1630
|
+
const refData = refDataIn;
|
|
1569
1631
|
const counter = refData[SPLITTER];
|
|
1570
1632
|
for (let i = counter; --i; ) {
|
|
1571
1633
|
key = SPLITTER + i;
|
|
@@ -1585,13 +1647,19 @@ var Updater = class {
|
|
|
1585
1647
|
/** Ref data for template rendering */
|
|
1586
1648
|
refData;
|
|
1587
1649
|
/** Changed keys in current digest cycle */
|
|
1588
|
-
changedKeys =
|
|
1650
|
+
changedKeys = /* @__PURE__ */ new Set();
|
|
1589
1651
|
/** Whether data has changed since last digest */
|
|
1590
1652
|
hasChangedFlag = 0;
|
|
1591
|
-
/**
|
|
1653
|
+
/**
|
|
1654
|
+
* Digesting queue: supports re-digest during digest.
|
|
1655
|
+
* Holds pending callbacks; `null` is used as a sentinel marking the start
|
|
1656
|
+
* of an active digest cycle, so `runDigest` can detect re-entrant calls.
|
|
1657
|
+
*/
|
|
1592
1658
|
digestingQueue = [];
|
|
1593
|
-
/**
|
|
1594
|
-
|
|
1659
|
+
/** Monotonically increasing version, bumped each time data actually changes. */
|
|
1660
|
+
version = 0;
|
|
1661
|
+
/** Snapshot of `version` taken by `snapshot()`, used by `altered()`. */
|
|
1662
|
+
snapshotVersion;
|
|
1595
1663
|
constructor(viewId) {
|
|
1596
1664
|
this.viewId = viewId;
|
|
1597
1665
|
this.data = { vId: viewId };
|
|
@@ -1619,7 +1687,16 @@ var Updater = class {
|
|
|
1619
1687
|
* Returns this for chaining.
|
|
1620
1688
|
*/
|
|
1621
1689
|
set(data, excludes) {
|
|
1622
|
-
|
|
1690
|
+
const changed = setData(
|
|
1691
|
+
data,
|
|
1692
|
+
this.data,
|
|
1693
|
+
this.changedKeys,
|
|
1694
|
+
excludes || EMPTY_STRING_SET
|
|
1695
|
+
);
|
|
1696
|
+
if (changed) {
|
|
1697
|
+
this.version++;
|
|
1698
|
+
this.hasChangedFlag = 1;
|
|
1699
|
+
}
|
|
1623
1700
|
return this;
|
|
1624
1701
|
}
|
|
1625
1702
|
/**
|
|
@@ -1655,13 +1732,13 @@ var Updater = class {
|
|
|
1655
1732
|
const keys2 = this.changedKeys;
|
|
1656
1733
|
const changed = this.hasChangedFlag;
|
|
1657
1734
|
this.hasChangedFlag = 0;
|
|
1658
|
-
this.changedKeys =
|
|
1735
|
+
this.changedKeys = /* @__PURE__ */ new Set();
|
|
1659
1736
|
const frame = Frame.get(this.viewId);
|
|
1660
1737
|
const view = frame?.view;
|
|
1661
1738
|
const node = getById(this.viewId);
|
|
1662
|
-
if (changed && view && node && view.signature > 0) {
|
|
1739
|
+
if (changed && view && node && view.signature > 0 && frame) {
|
|
1663
1740
|
const template = view.template;
|
|
1664
|
-
if (
|
|
1741
|
+
if (typeof template === "function") {
|
|
1665
1742
|
const html = template(
|
|
1666
1743
|
this.data,
|
|
1667
1744
|
this.viewId,
|
|
@@ -1698,43 +1775,65 @@ var Updater = class {
|
|
|
1698
1775
|
}
|
|
1699
1776
|
}
|
|
1700
1777
|
/**
|
|
1701
|
-
* Save a snapshot of current data for altered() detection.
|
|
1778
|
+
* Save a snapshot of the current data version for `altered()` detection.
|
|
1779
|
+
* Cheap O(1) — records the current monotonic version, no serialization.
|
|
1702
1780
|
*/
|
|
1703
1781
|
snapshot() {
|
|
1704
|
-
this.
|
|
1782
|
+
this.snapshotVersion = this.version;
|
|
1705
1783
|
return this;
|
|
1706
1784
|
}
|
|
1707
1785
|
/**
|
|
1708
|
-
* Check
|
|
1786
|
+
* Check whether data has changed since the last snapshot.
|
|
1787
|
+
* Returns undefined when no snapshot has been taken yet.
|
|
1709
1788
|
*/
|
|
1710
1789
|
altered() {
|
|
1711
|
-
if (this.
|
|
1712
|
-
|
|
1713
|
-
}
|
|
1714
|
-
return void 0;
|
|
1790
|
+
if (this.snapshotVersion === void 0) return void 0;
|
|
1791
|
+
return this.version !== this.snapshotVersion;
|
|
1715
1792
|
}
|
|
1716
1793
|
/**
|
|
1717
|
-
* Translate
|
|
1794
|
+
* Translate a refData reference back to its original value.
|
|
1795
|
+
*
|
|
1796
|
+
* The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
|
|
1797
|
+
* emitted by `updaterRef`. We require that exact shape so a user-supplied
|
|
1798
|
+
* string that merely begins with SPLITTER is never accidentally resolved
|
|
1799
|
+
* (or mishandled as a "missing ref").
|
|
1718
1800
|
*/
|
|
1719
1801
|
translate(data) {
|
|
1720
|
-
if (typeof data
|
|
1721
|
-
|
|
1802
|
+
if (typeof data !== "string") return data;
|
|
1803
|
+
if (data.length < 2 || data[0] !== SPLITTER) return data;
|
|
1804
|
+
for (let i = 1; i < data.length; i++) {
|
|
1805
|
+
const c = data.charCodeAt(i);
|
|
1806
|
+
if (c < 48 || c > 57) return data;
|
|
1722
1807
|
}
|
|
1723
|
-
return data;
|
|
1808
|
+
return hasOwnProperty(this.refData, data) ? this.refData[data] : data;
|
|
1724
1809
|
}
|
|
1725
1810
|
/**
|
|
1726
|
-
*
|
|
1811
|
+
* Resolve a dotted property path against refData.
|
|
1812
|
+
*
|
|
1813
|
+
* Only safe property-path syntax is supported: `a`, `a.b`, `a.b.c`.
|
|
1814
|
+
* Numeric literals (e.g. `1`, `1.5`) are returned as numbers. Anything else
|
|
1815
|
+
* returns `undefined` — we no longer evaluate arbitrary JavaScript via
|
|
1816
|
+
* `new Function`, so the method is CSP-safe and cannot be used as an
|
|
1817
|
+
* injection vector.
|
|
1727
1818
|
*/
|
|
1728
1819
|
parse(expr) {
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1820
|
+
const trimmed = expr.trim();
|
|
1821
|
+
if (!trimmed) return void 0;
|
|
1822
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) {
|
|
1823
|
+
return Number(trimmed);
|
|
1824
|
+
}
|
|
1825
|
+
if (!/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(trimmed)) {
|
|
1733
1826
|
return void 0;
|
|
1734
1827
|
}
|
|
1828
|
+
let cur = this.refData;
|
|
1829
|
+
for (const segment of trimmed.split(".")) {
|
|
1830
|
+
if (cur == null || typeof cur !== "object") return void 0;
|
|
1831
|
+
cur = cur[segment];
|
|
1832
|
+
}
|
|
1833
|
+
return cur;
|
|
1735
1834
|
}
|
|
1736
1835
|
/**
|
|
1737
|
-
* Get
|
|
1836
|
+
* Get the set of keys changed since the last digest (for external inspection).
|
|
1738
1837
|
*/
|
|
1739
1838
|
getChangedKeys() {
|
|
1740
1839
|
return this.changedKeys;
|
|
@@ -1781,30 +1880,31 @@ var View = class _View {
|
|
|
1781
1880
|
// ============================================================
|
|
1782
1881
|
// Getters for prototype-stored event maps
|
|
1783
1882
|
// ============================================================
|
|
1883
|
+
/** Prototype-stored event maps shape (set by View.prepare). */
|
|
1884
|
+
get protoEventState() {
|
|
1885
|
+
return Object.getPrototypeOf(this);
|
|
1886
|
+
}
|
|
1784
1887
|
/**
|
|
1785
1888
|
* Event bitmask map: eventType -> bitmask (1=root, 2=selector).
|
|
1786
1889
|
* Read from prototype ($evtObjMap) set by View.prepare.
|
|
1787
1890
|
* Using a getter avoids ES6 class field shadowing the prototype value.
|
|
1788
1891
|
*/
|
|
1789
1892
|
get eventObjectMap() {
|
|
1790
|
-
|
|
1791
|
-
return proto["$evtObjMap"] || {};
|
|
1893
|
+
return this.protoEventState.$evtObjMap ?? {};
|
|
1792
1894
|
}
|
|
1793
1895
|
/**
|
|
1794
1896
|
* Selector event map: eventType -> selector list.
|
|
1795
1897
|
* Read from prototype ($selMap) set by View.prepare.
|
|
1796
1898
|
*/
|
|
1797
1899
|
get eventSelectorMap() {
|
|
1798
|
-
|
|
1799
|
-
return proto["$selMap"] || {};
|
|
1900
|
+
return this.protoEventState.$selMap ?? {};
|
|
1800
1901
|
}
|
|
1801
1902
|
/**
|
|
1802
1903
|
* Global event list: [{handler, element, eventName, modifiers}].
|
|
1803
1904
|
* Read from prototype ($globalEvtList) set by View.prepare.
|
|
1804
1905
|
*/
|
|
1805
1906
|
get globalEventList() {
|
|
1806
|
-
|
|
1807
|
-
return proto["$globalEvtList"] || [];
|
|
1907
|
+
return this.protoEventState.$globalEvtList ?? [];
|
|
1808
1908
|
}
|
|
1809
1909
|
// ============================================================
|
|
1810
1910
|
// Instance lifecycle methods
|
|
@@ -1839,13 +1939,17 @@ var View = class _View {
|
|
|
1839
1939
|
// ============================================================
|
|
1840
1940
|
// Update methods
|
|
1841
1941
|
// ============================================================
|
|
1942
|
+
/** Get the owning frame, asserting it has been bound. */
|
|
1943
|
+
get ownerFrame() {
|
|
1944
|
+
return this.owner;
|
|
1945
|
+
}
|
|
1842
1946
|
/**
|
|
1843
1947
|
* Notify view that HTML update is about to begin.
|
|
1844
1948
|
* Unmounts child frames in the update zone.
|
|
1845
1949
|
*/
|
|
1846
1950
|
beginUpdate(id) {
|
|
1847
1951
|
if (this.signature > 0 && this.endUpdatePending !== void 0) {
|
|
1848
|
-
this.
|
|
1952
|
+
this.ownerFrame.unmountZone(id, true);
|
|
1849
1953
|
}
|
|
1850
1954
|
}
|
|
1851
1955
|
/**
|
|
@@ -1863,7 +1967,7 @@ var View = class _View {
|
|
|
1863
1967
|
this.endUpdatePending = 1;
|
|
1864
1968
|
this.rendered = true;
|
|
1865
1969
|
}
|
|
1866
|
-
const ownerFrame = this.
|
|
1970
|
+
const ownerFrame = this.ownerFrame;
|
|
1867
1971
|
ownerFrame.mountZone(updateId, inner);
|
|
1868
1972
|
if (!flag) {
|
|
1869
1973
|
setTimeout(
|
|
@@ -1902,11 +2006,12 @@ var View = class _View {
|
|
|
1902
2006
|
const loc = this.locationObserved;
|
|
1903
2007
|
loc.flag = 1;
|
|
1904
2008
|
if (typeof params === "object" && !Array.isArray(params)) {
|
|
1905
|
-
|
|
2009
|
+
const opts = params;
|
|
2010
|
+
if (opts["path"]) {
|
|
1906
2011
|
observePath = true;
|
|
1907
2012
|
}
|
|
1908
|
-
const paramKeys =
|
|
1909
|
-
if (paramKeys) {
|
|
2013
|
+
const paramKeys = opts["params"];
|
|
2014
|
+
if (typeof paramKeys === "string" || Array.isArray(paramKeys)) {
|
|
1910
2015
|
params = paramKeys;
|
|
1911
2016
|
}
|
|
1912
2017
|
}
|
|
@@ -1970,24 +2075,16 @@ var View = class _View {
|
|
|
1970
2075
|
*/
|
|
1971
2076
|
leaveTip(message, condition) {
|
|
1972
2077
|
const changeListener = function(e) {
|
|
1973
|
-
const isRouterChange = e.type ===
|
|
2078
|
+
const isRouterChange = e.type === RouterEvents.CHANGE;
|
|
1974
2079
|
const aKey = isRouterChange ? "a" : "b";
|
|
1975
2080
|
const bKey = isRouterChange ? "b" : "a";
|
|
1976
2081
|
if (changeListener[aKey]) {
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
}
|
|
1980
|
-
if (typeof e.reject === "function") {
|
|
1981
|
-
e.reject();
|
|
1982
|
-
}
|
|
2082
|
+
e.prevent?.();
|
|
2083
|
+
e.reject?.();
|
|
1983
2084
|
} else if (condition()) {
|
|
1984
|
-
|
|
1985
|
-
e.prevent();
|
|
1986
|
-
}
|
|
2085
|
+
e.prevent?.();
|
|
1987
2086
|
changeListener[bKey] = 1;
|
|
1988
|
-
|
|
1989
|
-
e.resolve();
|
|
1990
|
-
}
|
|
2087
|
+
e.resolve?.();
|
|
1991
2088
|
}
|
|
1992
2089
|
};
|
|
1993
2090
|
const unloadListener = (e) => {
|
|
@@ -1995,14 +2092,12 @@ var View = class _View {
|
|
|
1995
2092
|
e["msg"] = message;
|
|
1996
2093
|
}
|
|
1997
2094
|
};
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
Router.on(ROUTER_EVENTS.PAGE_UNLOAD, unloadFn);
|
|
2002
|
-
this.on("unload", changeFn);
|
|
2095
|
+
Router.on(RouterEvents.CHANGE, changeListener);
|
|
2096
|
+
Router.on(RouterEvents.PAGE_UNLOAD, unloadListener);
|
|
2097
|
+
this.on("unload", changeListener);
|
|
2003
2098
|
this.on("destroy", () => {
|
|
2004
|
-
Router.off(
|
|
2005
|
-
Router.off(
|
|
2099
|
+
Router.off(RouterEvents.CHANGE, changeListener);
|
|
2100
|
+
Router.off(RouterEvents.PAGE_UNLOAD, unloadListener);
|
|
2006
2101
|
});
|
|
2007
2102
|
}
|
|
2008
2103
|
// ============================================================
|
|
@@ -2032,7 +2127,7 @@ var View = class _View {
|
|
|
2032
2127
|
_View.mergeMixins(mixins, oView, ctors);
|
|
2033
2128
|
}
|
|
2034
2129
|
for (const p in proto) {
|
|
2035
|
-
if (!
|
|
2130
|
+
if (!hasOwnProperty(proto, p)) continue;
|
|
2036
2131
|
const currentFn = proto[p];
|
|
2037
2132
|
if (typeof currentFn !== "function") continue;
|
|
2038
2133
|
const matches = p.match(VIEW_EVENT_METHOD_REGEXP);
|
|
@@ -2078,16 +2173,16 @@ var View = class _View {
|
|
|
2078
2173
|
const existingFn = proto[combinedKey];
|
|
2079
2174
|
if (!existingFn) {
|
|
2080
2175
|
proto[combinedKey] = currentFn;
|
|
2081
|
-
} else {
|
|
2176
|
+
} else if (typeof existingFn === "function") {
|
|
2082
2177
|
const mixinFn = currentFn;
|
|
2083
2178
|
const existingMixin = existingFn;
|
|
2084
2179
|
if (existingMixin.marker) {
|
|
2085
2180
|
if (mixinFn.marker) {
|
|
2086
2181
|
proto[combinedKey] = _View.processMixinsSameEvent(
|
|
2087
|
-
|
|
2088
|
-
|
|
2182
|
+
mixinFn,
|
|
2183
|
+
existingMixin
|
|
2089
2184
|
);
|
|
2090
|
-
} else if (
|
|
2185
|
+
} else if (hasOwnProperty(proto, p)) {
|
|
2091
2186
|
proto[combinedKey] = currentFn;
|
|
2092
2187
|
}
|
|
2093
2188
|
}
|
|
@@ -2110,7 +2205,7 @@ var View = class _View {
|
|
|
2110
2205
|
const selectorObject = view.eventSelectorMap;
|
|
2111
2206
|
const eventsList = view.globalEventList;
|
|
2112
2207
|
for (const e in eventsObject) {
|
|
2113
|
-
if (
|
|
2208
|
+
if (hasOwnProperty(eventsObject, e)) {
|
|
2114
2209
|
if (destroy) {
|
|
2115
2210
|
EventDelegator.unbind(e, !!selectorObject[e]);
|
|
2116
2211
|
} else {
|
|
@@ -2153,7 +2248,7 @@ var View = class _View {
|
|
|
2153
2248
|
static destroyAllResources(view, lastly) {
|
|
2154
2249
|
const cache = view.resources;
|
|
2155
2250
|
for (const p in cache) {
|
|
2156
|
-
if (
|
|
2251
|
+
if (hasOwnProperty(cache, p)) {
|
|
2157
2252
|
const entry = cache[p];
|
|
2158
2253
|
if (lastly || entry.destroyOnRender) {
|
|
2159
2254
|
_View.destroyResource(cache, p, true);
|
|
@@ -2183,13 +2278,16 @@ var View = class _View {
|
|
|
2183
2278
|
static wrapMethod(proto, fnName, shortKey) {
|
|
2184
2279
|
const originalFn = proto[fnName];
|
|
2185
2280
|
if (typeof originalFn !== "function") return;
|
|
2281
|
+
const originalAsFn = originalFn;
|
|
2186
2282
|
const wrapped = function(...args) {
|
|
2187
2283
|
if (this.signature > 0) {
|
|
2188
2284
|
this.signature++;
|
|
2189
2285
|
this.fire("render");
|
|
2190
2286
|
_View.destroyAllResources(this, false);
|
|
2191
|
-
const
|
|
2192
|
-
const
|
|
2287
|
+
const lookup = this;
|
|
2288
|
+
const candidate = lookup[fnName];
|
|
2289
|
+
const instanceFn = typeof candidate === "function" ? candidate : originalAsFn;
|
|
2290
|
+
const fnToCall = instanceFn === wrapped ? originalAsFn : instanceFn;
|
|
2193
2291
|
return funcWithTry(fnToCall, args, this, noop);
|
|
2194
2292
|
}
|
|
2195
2293
|
return void 0;
|
|
@@ -2203,19 +2301,18 @@ var View = class _View {
|
|
|
2203
2301
|
*/
|
|
2204
2302
|
static processMixinsSameEvent(additional, exist) {
|
|
2205
2303
|
let temp;
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
temp = existMixin;
|
|
2304
|
+
if (exist.handlerList) {
|
|
2305
|
+
temp = exist;
|
|
2209
2306
|
} else {
|
|
2210
|
-
|
|
2211
|
-
funcWithTry(
|
|
2307
|
+
const merged = function(...e) {
|
|
2308
|
+
funcWithTry(merged.handlerList ?? [], e, this, noop);
|
|
2212
2309
|
};
|
|
2213
|
-
|
|
2214
|
-
|
|
2310
|
+
merged.handlerList = [exist];
|
|
2311
|
+
merged.marker = 1;
|
|
2312
|
+
temp = merged;
|
|
2215
2313
|
}
|
|
2216
|
-
const additionalMixin = additional;
|
|
2217
2314
|
temp.handlerList = (temp.handlerList ?? []).concat(
|
|
2218
|
-
|
|
2315
|
+
additional.handlerList ?? [additional]
|
|
2219
2316
|
);
|
|
2220
2317
|
return temp;
|
|
2221
2318
|
}
|
|
@@ -2227,29 +2324,29 @@ var View = class _View {
|
|
|
2227
2324
|
const temp = {};
|
|
2228
2325
|
for (const node of mixins) {
|
|
2229
2326
|
for (const p in node) {
|
|
2230
|
-
if (!
|
|
2327
|
+
if (!hasOwnProperty(node, p)) continue;
|
|
2231
2328
|
const fn = node[p];
|
|
2329
|
+
if (typeof fn !== "function") continue;
|
|
2330
|
+
const mixinFn = fn;
|
|
2232
2331
|
const exist = temp[p];
|
|
2233
2332
|
if (p === "make") {
|
|
2234
|
-
ctors.push(
|
|
2333
|
+
ctors.push(mixinFn);
|
|
2235
2334
|
continue;
|
|
2236
2335
|
}
|
|
2237
2336
|
if (VIEW_EVENT_METHOD_REGEXP.test(p)) {
|
|
2238
2337
|
if (exist) {
|
|
2239
|
-
temp[p] = _View.processMixinsSameEvent(
|
|
2338
|
+
temp[p] = _View.processMixinsSameEvent(mixinFn, exist);
|
|
2240
2339
|
} else {
|
|
2241
|
-
|
|
2242
|
-
temp[p] =
|
|
2243
|
-
}
|
|
2244
|
-
} else {
|
|
2245
|
-
if (!exist) {
|
|
2246
|
-
temp[p] = fn;
|
|
2340
|
+
mixinFn.marker = 1;
|
|
2341
|
+
temp[p] = mixinFn;
|
|
2247
2342
|
}
|
|
2343
|
+
} else if (!exist) {
|
|
2344
|
+
temp[p] = mixinFn;
|
|
2248
2345
|
}
|
|
2249
2346
|
}
|
|
2250
2347
|
}
|
|
2251
2348
|
for (const p in temp) {
|
|
2252
|
-
if (!
|
|
2349
|
+
if (!hasOwnProperty(proto, p)) {
|
|
2253
2350
|
proto[p] = temp[p];
|
|
2254
2351
|
}
|
|
2255
2352
|
}
|
|
@@ -2282,19 +2379,20 @@ var View = class _View {
|
|
|
2282
2379
|
* - Event method patterns: `'name<click>'` etc.
|
|
2283
2380
|
*/
|
|
2284
2381
|
static extend(props, statics) {
|
|
2285
|
-
|
|
2286
|
-
const make =
|
|
2382
|
+
const definedProps = props ?? {};
|
|
2383
|
+
const make = definedProps["make"];
|
|
2287
2384
|
const ctors = [];
|
|
2288
|
-
if (make) {
|
|
2385
|
+
if (typeof make === "function") {
|
|
2289
2386
|
ctors.push(make);
|
|
2290
2387
|
}
|
|
2291
2388
|
const ParentView = this;
|
|
2292
2389
|
const ChildView = class extends ParentView {
|
|
2293
2390
|
constructor(nodeId, ownerFrame, initParams, node, mixinCtors) {
|
|
2294
2391
|
super(nodeId, ownerFrame, initParams, node, []);
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2392
|
+
const instanceProps = this;
|
|
2393
|
+
for (const key in definedProps) {
|
|
2394
|
+
if (hasOwnProperty(definedProps, key) && key !== "make" && key !== "render") {
|
|
2395
|
+
instanceProps[key] = definedProps[key];
|
|
2298
2396
|
}
|
|
2299
2397
|
}
|
|
2300
2398
|
this.id = nodeId;
|
|
@@ -2314,15 +2412,16 @@ var View = class _View {
|
|
|
2314
2412
|
}
|
|
2315
2413
|
};
|
|
2316
2414
|
const proto = ChildView.prototype;
|
|
2317
|
-
for (const key in
|
|
2318
|
-
if (
|
|
2319
|
-
proto[key] =
|
|
2415
|
+
for (const key in definedProps) {
|
|
2416
|
+
if (hasOwnProperty(definedProps, key) && key !== "make") {
|
|
2417
|
+
proto[key] = definedProps[key];
|
|
2320
2418
|
}
|
|
2321
2419
|
}
|
|
2322
2420
|
if (statics) {
|
|
2421
|
+
const staticTarget = ChildView;
|
|
2323
2422
|
for (const key in statics) {
|
|
2324
|
-
if (
|
|
2325
|
-
|
|
2423
|
+
if (hasOwnProperty(statics, key)) {
|
|
2424
|
+
staticTarget[key] = statics[key];
|
|
2326
2425
|
}
|
|
2327
2426
|
}
|
|
2328
2427
|
}
|
|
@@ -2337,14 +2436,86 @@ var View = class _View {
|
|
|
2337
2436
|
return this;
|
|
2338
2437
|
}
|
|
2339
2438
|
};
|
|
2439
|
+
function defineView(props, statics) {
|
|
2440
|
+
return View.extend(props, statics);
|
|
2441
|
+
}
|
|
2442
|
+
|
|
2443
|
+
// src/module-loader.ts
|
|
2444
|
+
var config = {
|
|
2445
|
+
rootId: "root",
|
|
2446
|
+
hashbang: "#!",
|
|
2447
|
+
error: (error) => {
|
|
2448
|
+
throw error;
|
|
2449
|
+
}
|
|
2450
|
+
};
|
|
2451
|
+
function use(names, callback) {
|
|
2452
|
+
const nameList = typeof names === "string" ? [names] : names;
|
|
2453
|
+
const loadPromise = (() => {
|
|
2454
|
+
if (config.require) {
|
|
2455
|
+
const result = config.require(nameList);
|
|
2456
|
+
if (result && typeof result.then === "function") {
|
|
2457
|
+
return result;
|
|
2458
|
+
}
|
|
2459
|
+
return Promise.resolve([]);
|
|
2460
|
+
}
|
|
2461
|
+
return Promise.all(
|
|
2462
|
+
nameList.map((name) => {
|
|
2463
|
+
const importPath = name.startsWith(".") || name.startsWith("/") ? name : `./${name}`;
|
|
2464
|
+
return import(
|
|
2465
|
+
/* @vite-ignore */
|
|
2466
|
+
/* webpackIgnore: true */
|
|
2467
|
+
importPath
|
|
2468
|
+
).then((mod) => {
|
|
2469
|
+
return mod && (mod["__esModule"] || // For Webpack
|
|
2470
|
+
typeof mod["default"] === "function") ? mod["default"] : mod;
|
|
2471
|
+
}).catch((err) => {
|
|
2472
|
+
const errorHandler = config.error;
|
|
2473
|
+
if (errorHandler) {
|
|
2474
|
+
errorHandler(err instanceof Error ? err : new Error(String(err)));
|
|
2475
|
+
}
|
|
2476
|
+
return void 0;
|
|
2477
|
+
});
|
|
2478
|
+
})
|
|
2479
|
+
);
|
|
2480
|
+
})();
|
|
2481
|
+
if (callback) {
|
|
2482
|
+
loadPromise.then((modules) => {
|
|
2483
|
+
callback(...modules);
|
|
2484
|
+
});
|
|
2485
|
+
}
|
|
2486
|
+
return loadPromise;
|
|
2487
|
+
}
|
|
2488
|
+
|
|
2489
|
+
// src/view-registry.ts
|
|
2490
|
+
var viewClassRegistry = {};
|
|
2491
|
+
function getViewClass(path) {
|
|
2492
|
+
return viewClassRegistry[path];
|
|
2493
|
+
}
|
|
2494
|
+
function registerViewClass(viewPath, ViewClass) {
|
|
2495
|
+
const parsed = parseUri(viewPath);
|
|
2496
|
+
const path = parsed.path;
|
|
2497
|
+
if (path) {
|
|
2498
|
+
viewClassRegistry[path] = ViewClass;
|
|
2499
|
+
}
|
|
2500
|
+
}
|
|
2501
|
+
function invalidateViewClass(viewPath) {
|
|
2502
|
+
const parsed = parseUri(viewPath);
|
|
2503
|
+
const path = parsed.path;
|
|
2504
|
+
if (path) {
|
|
2505
|
+
Reflect.deleteProperty(viewClassRegistry, path);
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
function getViewClassRegistry() {
|
|
2509
|
+
return viewClassRegistry;
|
|
2510
|
+
}
|
|
2340
2511
|
|
|
2341
2512
|
// src/frame.ts
|
|
2342
2513
|
var frameRegistry = /* @__PURE__ */ new Map();
|
|
2343
2514
|
var rootFrame;
|
|
2344
2515
|
var globalAlter;
|
|
2516
|
+
var MAX_FRAME_POOL = 64;
|
|
2345
2517
|
var frameCache = [];
|
|
2346
2518
|
var staticEmitter = new EventEmitter();
|
|
2347
|
-
var viewClassRegistry = {};
|
|
2348
2519
|
var Frame = class _Frame extends EventEmitter {
|
|
2349
2520
|
/** Frame ID (same as owner DOM element ID) */
|
|
2350
2521
|
id;
|
|
@@ -2359,8 +2530,8 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2359
2530
|
childrenCount = 0;
|
|
2360
2531
|
/** Ready count (children that have fired 'created') */
|
|
2361
2532
|
readyCount = 0;
|
|
2362
|
-
/**
|
|
2363
|
-
readyMap =
|
|
2533
|
+
/** Set of child frame IDs that have fired 'created' */
|
|
2534
|
+
readyMap = /* @__PURE__ */ new Set();
|
|
2364
2535
|
/** View instance */
|
|
2365
2536
|
viewInstance;
|
|
2366
2537
|
/** Get view instance (read-only) */
|
|
@@ -2431,13 +2602,30 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2431
2602
|
this.viewPath = viewPath;
|
|
2432
2603
|
const params = parsed["params"];
|
|
2433
2604
|
translateQuery(pId || this.id, viewPath, params);
|
|
2605
|
+
const initParams = { ...params };
|
|
2434
2606
|
if (viewInitParams) {
|
|
2435
|
-
assign(
|
|
2607
|
+
assign(initParams, viewInitParams);
|
|
2436
2608
|
}
|
|
2437
2609
|
const sign = this.signature;
|
|
2438
|
-
|
|
2439
|
-
|
|
2610
|
+
const registered = getViewClass(viewClassName);
|
|
2611
|
+
if (registered) {
|
|
2612
|
+
this.doMountView(registered, initParams, node, sign);
|
|
2613
|
+
return;
|
|
2440
2614
|
}
|
|
2615
|
+
use(viewClassName, (ViewClass) => {
|
|
2616
|
+
if (sign !== this.signature) return;
|
|
2617
|
+
if (typeof ViewClass === "function") {
|
|
2618
|
+
const ViewClassTyped = ViewClass;
|
|
2619
|
+
registerViewClass(viewClassName, ViewClassTyped);
|
|
2620
|
+
this.doMountView(ViewClassTyped, initParams, node, sign);
|
|
2621
|
+
} else {
|
|
2622
|
+
const error = new Error(`Cannot load view: ${viewClassName}`);
|
|
2623
|
+
const errorHandler = config.error;
|
|
2624
|
+
if (errorHandler) {
|
|
2625
|
+
errorHandler(error);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
});
|
|
2441
2629
|
}
|
|
2442
2630
|
/**
|
|
2443
2631
|
* Internal: actually mount the view after class is loaded.
|
|
@@ -2445,14 +2633,8 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2445
2633
|
doMountView(ViewClass, params, node, sign) {
|
|
2446
2634
|
if (sign !== this.signature) return;
|
|
2447
2635
|
const mixinCtors = View.prepare(ViewClass);
|
|
2448
|
-
const
|
|
2449
|
-
const view = new
|
|
2450
|
-
this.id,
|
|
2451
|
-
this,
|
|
2452
|
-
params,
|
|
2453
|
-
node,
|
|
2454
|
-
mixinCtors
|
|
2455
|
-
);
|
|
2636
|
+
const Ctor = ViewClass;
|
|
2637
|
+
const view = new Ctor(this.id, this, params, node, mixinCtors);
|
|
2456
2638
|
this.viewInstance = view;
|
|
2457
2639
|
view.signature = 1;
|
|
2458
2640
|
View.delegateEvents(view);
|
|
@@ -2533,7 +2715,9 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2533
2715
|
frame.unmountView();
|
|
2534
2716
|
removeFrame(targetId, wasCreated);
|
|
2535
2717
|
reInitFrameForCache(frame);
|
|
2536
|
-
frameCache.
|
|
2718
|
+
if (frameCache.length < MAX_FRAME_POOL) {
|
|
2719
|
+
frameCache.push(frame);
|
|
2720
|
+
}
|
|
2537
2721
|
const parent = frameRegistry.get(pId || "");
|
|
2538
2722
|
if (parent && parent.childrenMap[targetId]) {
|
|
2539
2723
|
Reflect.deleteProperty(parent.childrenMap, targetId);
|
|
@@ -2552,13 +2736,12 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2552
2736
|
const viewElements = rootEl.querySelectorAll(`[${LARK_VIEW}]`);
|
|
2553
2737
|
const frames = [];
|
|
2554
2738
|
viewElements.forEach((el) => {
|
|
2555
|
-
|
|
2556
|
-
if (
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
}
|
|
2739
|
+
if (!(el instanceof HTMLElement)) return;
|
|
2740
|
+
if (htmlElIsBound(el)) return;
|
|
2741
|
+
const elId = ensureElementId2(el);
|
|
2742
|
+
el.frameBound = 1;
|
|
2743
|
+
const viewPath = getAttribute(el, LARK_VIEW);
|
|
2744
|
+
frames.push([elId, viewPath]);
|
|
2562
2745
|
});
|
|
2563
2746
|
for (const [frameId, viewPath] of frames) {
|
|
2564
2747
|
this.mountFrame(frameId, viewPath);
|
|
@@ -2571,7 +2754,7 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2571
2754
|
*/
|
|
2572
2755
|
unmountZone(zoneId, _inner) {
|
|
2573
2756
|
for (const childId in this.childrenMap) {
|
|
2574
|
-
if (
|
|
2757
|
+
if (hasOwnProperty(this.childrenMap, childId)) {
|
|
2575
2758
|
if (!zoneId || childId !== zoneId) {
|
|
2576
2759
|
this.unmountFrame(childId);
|
|
2577
2760
|
}
|
|
@@ -2585,7 +2768,7 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2585
2768
|
children() {
|
|
2586
2769
|
const result = [];
|
|
2587
2770
|
for (const id in this.childrenMap) {
|
|
2588
|
-
if (
|
|
2771
|
+
if (hasOwnProperty(this.childrenMap, id)) {
|
|
2589
2772
|
result.push(id);
|
|
2590
2773
|
}
|
|
2591
2774
|
}
|
|
@@ -2612,14 +2795,10 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2612
2795
|
let result;
|
|
2613
2796
|
const view = this.view;
|
|
2614
2797
|
if (view && view.rendered) {
|
|
2615
|
-
const
|
|
2798
|
+
const lookup = view;
|
|
2799
|
+
const fn = lookup[name];
|
|
2616
2800
|
if (typeof fn === "function") {
|
|
2617
|
-
result = funcWithTry(
|
|
2618
|
-
fn,
|
|
2619
|
-
args || [],
|
|
2620
|
-
view,
|
|
2621
|
-
noop
|
|
2622
|
-
);
|
|
2801
|
+
result = funcWithTry(fn, args || [], view, noop);
|
|
2623
2802
|
}
|
|
2624
2803
|
} else {
|
|
2625
2804
|
const key = SPLITTER + name;
|
|
@@ -2642,6 +2821,25 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2642
2821
|
}
|
|
2643
2822
|
return result;
|
|
2644
2823
|
}
|
|
2824
|
+
/**
|
|
2825
|
+
* Type-safe variant of `invoke`.
|
|
2826
|
+
*
|
|
2827
|
+
* `invoke()` accepts any string and any args, which silently hides
|
|
2828
|
+
* mismatched call sites when a method gets renamed. `invokeTyped` carries
|
|
2829
|
+
* the view's method signature through TypeScript so the compiler catches
|
|
2830
|
+
* those mistakes:
|
|
2831
|
+
*
|
|
2832
|
+
* ```ts
|
|
2833
|
+
* type Home = View & { loadData(id: string): Promise<void> };
|
|
2834
|
+
* frame.invokeTyped<Home, "loadData">("loadData", ["user-1"]);
|
|
2835
|
+
* ```
|
|
2836
|
+
*
|
|
2837
|
+
* Behavior is identical to `invoke` at runtime — same defer / direct-call
|
|
2838
|
+
* paths — so it's a drop-in safer overload.
|
|
2839
|
+
*/
|
|
2840
|
+
invokeTyped(name, args) {
|
|
2841
|
+
return this.invoke(name, args);
|
|
2842
|
+
}
|
|
2645
2843
|
// ============================================================
|
|
2646
2844
|
// Static methods
|
|
2647
2845
|
// ============================================================
|
|
@@ -2653,8 +2851,25 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2653
2851
|
static getAll() {
|
|
2654
2852
|
return frameRegistry;
|
|
2655
2853
|
}
|
|
2656
|
-
/**
|
|
2657
|
-
|
|
2854
|
+
/**
|
|
2855
|
+
* Returns the existing root frame, or `undefined` if none has been created.
|
|
2856
|
+
* Pure getter — never creates a Frame, never touches the DOM.
|
|
2857
|
+
*
|
|
2858
|
+
* Use `Frame.createRoot(id)` to create the root explicitly during framework
|
|
2859
|
+
* boot. For Micro-Frontend hosts that own multiple independent containers,
|
|
2860
|
+
* use `new Frame(containerId)` directly so each MF mount has its own root.
|
|
2861
|
+
*/
|
|
2862
|
+
static getRoot() {
|
|
2863
|
+
return rootFrame;
|
|
2864
|
+
}
|
|
2865
|
+
/**
|
|
2866
|
+
* Create (or return) the singleton root frame for this app.
|
|
2867
|
+
*
|
|
2868
|
+
* Idempotent: subsequent calls always return the original root regardless
|
|
2869
|
+
* of `rootId` — so passing a different id later is silently ignored.
|
|
2870
|
+
* `Framework.boot()` is the canonical caller; user code rarely needs this.
|
|
2871
|
+
*/
|
|
2872
|
+
static createRoot(rootId) {
|
|
2658
2873
|
if (!rootFrame) {
|
|
2659
2874
|
rootId = rootId || "root";
|
|
2660
2875
|
let rootElement = document.getElementById(rootId);
|
|
@@ -2666,6 +2881,17 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2666
2881
|
}
|
|
2667
2882
|
return rootFrame;
|
|
2668
2883
|
}
|
|
2884
|
+
/**
|
|
2885
|
+
* @deprecated Use `Frame.getRoot()` for read-only access or
|
|
2886
|
+
* `Frame.createRoot(id)` to create the root explicitly. The single-method
|
|
2887
|
+
* `root()` blurred the distinction and was a common source of bugs in
|
|
2888
|
+
* Micro-Frontend hosts.
|
|
2889
|
+
*
|
|
2890
|
+
* Kept for backward compatibility — behavior unchanged.
|
|
2891
|
+
*/
|
|
2892
|
+
static root(rootId) {
|
|
2893
|
+
return _Frame.createRoot(rootId);
|
|
2894
|
+
}
|
|
2669
2895
|
/** Bind event listener (static) */
|
|
2670
2896
|
static on(event, handler) {
|
|
2671
2897
|
staticEmitter.on(event, handler);
|
|
@@ -2681,6 +2907,9 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2681
2907
|
staticEmitter.fire(event, data);
|
|
2682
2908
|
}
|
|
2683
2909
|
};
|
|
2910
|
+
function htmlElIsBound(element) {
|
|
2911
|
+
return !!element.frameBound;
|
|
2912
|
+
}
|
|
2684
2913
|
function ensureElementId2(element) {
|
|
2685
2914
|
const id = element.getAttribute("id");
|
|
2686
2915
|
if (id) return id;
|
|
@@ -2710,8 +2939,8 @@ function notifyCreated(frameInstance) {
|
|
|
2710
2939
|
const pId = frameInstance.parentId;
|
|
2711
2940
|
if (pId) {
|
|
2712
2941
|
const parent = frameRegistry.get(pId);
|
|
2713
|
-
if (parent && !parent.readyMap
|
|
2714
|
-
parent.readyMap
|
|
2942
|
+
if (parent && !parent.readyMap.has(frameInstance.id)) {
|
|
2943
|
+
parent.readyMap.add(frameInstance.id);
|
|
2715
2944
|
parent.readyCount++;
|
|
2716
2945
|
notifyCreated(parent);
|
|
2717
2946
|
}
|
|
@@ -2726,9 +2955,9 @@ function notifyAlter(frameInstance, data) {
|
|
|
2726
2955
|
const pId = frameInstance.parentId;
|
|
2727
2956
|
if (pId) {
|
|
2728
2957
|
const parent = frameRegistry.get(pId);
|
|
2729
|
-
if (parent && parent.readyMap
|
|
2958
|
+
if (parent && parent.readyMap.has(frameInstance.id)) {
|
|
2730
2959
|
parent.readyCount--;
|
|
2731
|
-
|
|
2960
|
+
parent.readyMap.delete(frameInstance.id);
|
|
2732
2961
|
notifyAlter(parent, data);
|
|
2733
2962
|
}
|
|
2734
2963
|
}
|
|
@@ -2741,7 +2970,7 @@ function reInitFrame(frame, id, parentId) {
|
|
|
2741
2970
|
frame["childrenCount"] = 0;
|
|
2742
2971
|
frame["readyCount"] = 0;
|
|
2743
2972
|
frame["signature"] = 1;
|
|
2744
|
-
frame["readyMap"] =
|
|
2973
|
+
frame["readyMap"] = /* @__PURE__ */ new Set();
|
|
2745
2974
|
frame["invokeList"] = [];
|
|
2746
2975
|
frameRegistry.set(id, frame);
|
|
2747
2976
|
}
|
|
@@ -2749,7 +2978,7 @@ function reInitFrameForCache(frame) {
|
|
|
2749
2978
|
Reflect.set(frame, "id", "");
|
|
2750
2979
|
frame["_parentId"] = void 0;
|
|
2751
2980
|
frame["childrenMap"] = {};
|
|
2752
|
-
frame["readyMap"] =
|
|
2981
|
+
frame["readyMap"] = /* @__PURE__ */ new Set();
|
|
2753
2982
|
}
|
|
2754
2983
|
function translateQuery(pId, src, params) {
|
|
2755
2984
|
const parentFrame = frameRegistry.get(pId);
|
|
@@ -2759,22 +2988,138 @@ function translateQuery(pId, src, params) {
|
|
|
2759
2988
|
if (!parentRefData) return;
|
|
2760
2989
|
if (src.indexOf(SPLITTER) > 0) {
|
|
2761
2990
|
translateData(parentRefData, params);
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
);
|
|
2991
|
+
const paramsRec = params;
|
|
2992
|
+
const splitterValue = paramsRec[SPLITTER];
|
|
2993
|
+
if (splitterValue && typeof splitterValue === "object") {
|
|
2994
|
+
assign(params, splitterValue);
|
|
2767
2995
|
Reflect.deleteProperty(params, SPLITTER);
|
|
2768
2996
|
}
|
|
2769
2997
|
}
|
|
2770
2998
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2999
|
+
|
|
3000
|
+
// src/cross-site.ts
|
|
3001
|
+
var preparePromises = {};
|
|
3002
|
+
var projectsMap = null;
|
|
3003
|
+
function loadRemoteView(viewPath, bizCode) {
|
|
3004
|
+
const crossConfigs = config.crossConfigs || window.crossConfigs;
|
|
3005
|
+
const currentName = config.projectName || "";
|
|
3006
|
+
const slashIndex = viewPath.indexOf("/");
|
|
3007
|
+
const projectName = slashIndex > -1 ? viewPath.substring(0, slashIndex) : viewPath;
|
|
3008
|
+
if (projectName === currentName) return Promise.resolve();
|
|
3009
|
+
if (!preparePromises[projectName]) {
|
|
3010
|
+
if (!projectsMap) {
|
|
3011
|
+
const map = toMap(crossConfigs || [], "projectName");
|
|
3012
|
+
projectsMap = map;
|
|
3013
|
+
}
|
|
3014
|
+
const info = projectsMap[projectName];
|
|
3015
|
+
if (!info) {
|
|
3016
|
+
return Promise.reject(
|
|
3017
|
+
new Error(`Cannot find ${projectName} from crossConfigs`)
|
|
3018
|
+
);
|
|
3019
|
+
}
|
|
3020
|
+
preparePromises[projectName] = use(`${projectName}/prepare`).then((modules) => {
|
|
3021
|
+
let mod = modules[0];
|
|
3022
|
+
if (mod && typeof mod === "object" && mod !== null) {
|
|
3023
|
+
const rec = mod;
|
|
3024
|
+
if (rec["__esModule"]) {
|
|
3025
|
+
mod = rec["default"];
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
if (typeof mod === "function") {
|
|
3029
|
+
return mod({ bizCode });
|
|
3030
|
+
}
|
|
3031
|
+
return void 0;
|
|
3032
|
+
}).catch((err) => {
|
|
3033
|
+
Reflect.deleteProperty(preparePromises, projectName);
|
|
3034
|
+
throw err;
|
|
3035
|
+
});
|
|
2776
3036
|
}
|
|
3037
|
+
return preparePromises[projectName];
|
|
3038
|
+
}
|
|
3039
|
+
function resetProjectsMap() {
|
|
3040
|
+
projectsMap = null;
|
|
2777
3041
|
}
|
|
3042
|
+
var skeletonTemplate = (data, viewId) => {
|
|
3043
|
+
let skeletonHtml = "<div>Loading...</div>";
|
|
3044
|
+
if (data && typeof data === "object") {
|
|
3045
|
+
const candidate = data.skeleton;
|
|
3046
|
+
if (typeof candidate === "string") skeletonHtml = candidate;
|
|
3047
|
+
}
|
|
3048
|
+
return `<div id="mf_${viewId}">${skeletonHtml}</div>`;
|
|
3049
|
+
};
|
|
3050
|
+
var CrossSite = View.extend({
|
|
3051
|
+
/** Skeleton template renders loading state + child container */
|
|
3052
|
+
template: skeletonTemplate,
|
|
3053
|
+
init(params) {
|
|
3054
|
+
this.$sign = 0;
|
|
3055
|
+
this.on("destroy", () => {
|
|
3056
|
+
this.$sign = -1;
|
|
3057
|
+
});
|
|
3058
|
+
this.assign?.(params);
|
|
3059
|
+
},
|
|
3060
|
+
assign(data) {
|
|
3061
|
+
this.$view = typeof data["view"] === "string" ? data["view"] : "";
|
|
3062
|
+
const nested = data["params"];
|
|
3063
|
+
const nestedParams = nested && typeof nested === "object" ? nested : {};
|
|
3064
|
+
this.$params = { ...data, ...nestedParams };
|
|
3065
|
+
this.updater.set({
|
|
3066
|
+
skeleton: data["skeleton"],
|
|
3067
|
+
skeletonParams: data["skeletonParams"] || {},
|
|
3068
|
+
bizCode: data["bizCode"]
|
|
3069
|
+
});
|
|
3070
|
+
if (this.$sign > 0) {
|
|
3071
|
+
this.updateView();
|
|
3072
|
+
}
|
|
3073
|
+
return false;
|
|
3074
|
+
},
|
|
3075
|
+
async updateView() {
|
|
3076
|
+
const sign = ++this.$sign;
|
|
3077
|
+
const stored = this.updater.get();
|
|
3078
|
+
const bizCode = stored.bizCode;
|
|
3079
|
+
try {
|
|
3080
|
+
await loadRemoteView(this.$view, bizCode);
|
|
3081
|
+
} catch (ex) {
|
|
3082
|
+
const node = document.getElementById("mf_" + this.id);
|
|
3083
|
+
if (node) {
|
|
3084
|
+
const err = ex instanceof Error ? ex : new Error(String(ex));
|
|
3085
|
+
node.innerHTML = err.message || String(err);
|
|
3086
|
+
}
|
|
3087
|
+
}
|
|
3088
|
+
if (this.$sign !== sign) return;
|
|
3089
|
+
const mf = Frame.get("mf_" + this.id);
|
|
3090
|
+
const parsedNew = parseUri(this.$view);
|
|
3091
|
+
const newPath = parsedNew.path;
|
|
3092
|
+
const oldPath = mf?.viewPath ? parseUri(mf.viewPath).path : "";
|
|
3093
|
+
const view = mf?.view;
|
|
3094
|
+
if (newPath === oldPath && view && typeof view.assign === "function") {
|
|
3095
|
+
const result = funcWithTry(view.assign, [this.$params], view, noop);
|
|
3096
|
+
if (result) {
|
|
3097
|
+
view.render();
|
|
3098
|
+
}
|
|
3099
|
+
return;
|
|
3100
|
+
}
|
|
3101
|
+
const owner = this.owner;
|
|
3102
|
+
if (owner && typeof owner !== "number") {
|
|
3103
|
+
owner.mountFrame("mf_" + this.id, this.$view, this.$params);
|
|
3104
|
+
}
|
|
3105
|
+
},
|
|
3106
|
+
render() {
|
|
3107
|
+
const params = this.$params;
|
|
3108
|
+
this.updater.digest({
|
|
3109
|
+
skeleton: params?.["skeleton"]
|
|
3110
|
+
});
|
|
3111
|
+
this.updateView();
|
|
3112
|
+
},
|
|
3113
|
+
/**
|
|
3114
|
+
* Invoke a method on the remote view.
|
|
3115
|
+
* Usage: mf.invoke('callView', methodName, ...args)
|
|
3116
|
+
*/
|
|
3117
|
+
callView(name, ...args) {
|
|
3118
|
+
const mf = Frame.get("mf_" + this.id);
|
|
3119
|
+
return mf?.invoke(name, args);
|
|
3120
|
+
}
|
|
3121
|
+
});
|
|
3122
|
+
var cross_site_default = CrossSite;
|
|
2778
3123
|
|
|
2779
3124
|
// src/service.ts
|
|
2780
3125
|
var Payload = class {
|
|
@@ -2962,29 +3307,31 @@ var Service = class {
|
|
|
2962
3307
|
* Get metadata for an API endpoint.
|
|
2963
3308
|
*/
|
|
2964
3309
|
static meta(attrs) {
|
|
2965
|
-
const name = typeof attrs === "string" ? attrs : attrs["name"];
|
|
2966
|
-
|
|
3310
|
+
const name = typeof attrs === "string" ? attrs : String(attrs["name"] ?? "");
|
|
3311
|
+
const known = this._metaList[name];
|
|
3312
|
+
if (known) return known;
|
|
3313
|
+
return attrs;
|
|
2967
3314
|
}
|
|
2968
3315
|
/**
|
|
2969
3316
|
* Create a Payload for an API request.
|
|
2970
3317
|
*/
|
|
2971
3318
|
static create(attrs) {
|
|
2972
3319
|
const meta = this.meta(attrs);
|
|
2973
|
-
const cache = attrs["cache"]
|
|
3320
|
+
const cache = toCacheValue(attrs["cache"]) || meta.cache || 0;
|
|
2974
3321
|
const entity = new Payload();
|
|
2975
3322
|
entity.set(meta);
|
|
2976
3323
|
entity.cacheInfo = {
|
|
2977
3324
|
name: meta.name,
|
|
2978
|
-
after: meta.after,
|
|
2979
|
-
cleans: meta.cleanKeys,
|
|
3325
|
+
after: typeof meta.after === "function" ? meta.after : void 0,
|
|
3326
|
+
cleans: typeof meta.cleanKeys === "string" ? meta.cleanKeys : void 0,
|
|
2980
3327
|
key: cache ? defaultCacheKey(meta, attrs) : "",
|
|
2981
3328
|
time: 0
|
|
2982
3329
|
};
|
|
2983
|
-
if (
|
|
3330
|
+
if (attrs !== null) {
|
|
2984
3331
|
entity.set(attrs);
|
|
2985
3332
|
}
|
|
2986
3333
|
const before = meta.before;
|
|
2987
|
-
if (before) {
|
|
3334
|
+
if (typeof before === "function") {
|
|
2988
3335
|
funcWithTry(before, [entity], entity, noop);
|
|
2989
3336
|
}
|
|
2990
3337
|
this._staticEmitter.fire("begin", { payload: entity });
|
|
@@ -3010,7 +3357,7 @@ var Service = class {
|
|
|
3010
3357
|
*/
|
|
3011
3358
|
static cached(attrs) {
|
|
3012
3359
|
const meta = this.meta(attrs);
|
|
3013
|
-
const cache = attrs["cache"]
|
|
3360
|
+
const cache = toCacheValue(attrs["cache"]) || meta.cache || 0;
|
|
3014
3361
|
let cacheKey = "";
|
|
3015
3362
|
if (cache) {
|
|
3016
3363
|
cacheKey = defaultCacheKey(meta, attrs);
|
|
@@ -3018,7 +3365,8 @@ var Service = class {
|
|
|
3018
3365
|
if (cacheKey) {
|
|
3019
3366
|
const info = this._pendingCacheKeys[cacheKey];
|
|
3020
3367
|
if (info) {
|
|
3021
|
-
|
|
3368
|
+
const entity = info.entity;
|
|
3369
|
+
return entity instanceof Payload ? entity : void 0;
|
|
3022
3370
|
}
|
|
3023
3371
|
const cached = this._payloadCache.get(cacheKey);
|
|
3024
3372
|
if (cached && cached.cacheInfo) {
|
|
@@ -3035,17 +3383,14 @@ var Service = class {
|
|
|
3035
3383
|
* Clear cached payloads by endpoint name.
|
|
3036
3384
|
*/
|
|
3037
3385
|
static clear(names) {
|
|
3038
|
-
const
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
nameSet[n] = 1;
|
|
3042
|
-
}
|
|
3386
|
+
const nameSet = new Set(
|
|
3387
|
+
(typeof names === "string" ? names : names.join(",")).split(",")
|
|
3388
|
+
);
|
|
3043
3389
|
const keysToDelete = [];
|
|
3044
3390
|
this._payloadCache.forEach((payload) => {
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
}
|
|
3391
|
+
const info = payload?.cacheInfo;
|
|
3392
|
+
if (info && info.key && nameSet.has(info.name)) {
|
|
3393
|
+
keysToDelete.push(info.key);
|
|
3049
3394
|
}
|
|
3050
3395
|
});
|
|
3051
3396
|
for (const key of keysToDelete) {
|
|
@@ -3064,12 +3409,23 @@ var Service = class {
|
|
|
3064
3409
|
}
|
|
3065
3410
|
/**
|
|
3066
3411
|
* Create a new Service subclass with a custom sync function.
|
|
3067
|
-
*
|
|
3068
|
-
*
|
|
3412
|
+
*
|
|
3413
|
+
* Each subclass gets its OWN copies of every per-type static field
|
|
3414
|
+
* (`_metaList`, `_payloadCache`, `_pendingCacheKeys`, `_syncFn`,
|
|
3415
|
+
* `_staticEmitter`, `_cacheMax`, `_cacheBuffer`) via `static override`.
|
|
3416
|
+
* This is intentional: it ensures that endpoint metadata, cache state,
|
|
3417
|
+
* in-flight dedup keys, and event subscribers are fully isolated between
|
|
3418
|
+
* different Service types, even when one extends another.
|
|
3419
|
+
*
|
|
3420
|
+
* **Do not refactor these `static override` declarations away** — sharing
|
|
3421
|
+
* them through prototype inheritance would let endpoints registered on one
|
|
3422
|
+
* subclass leak into another, and the LFU cache evictions of one type
|
|
3423
|
+
* would race with those of another.
|
|
3069
3424
|
*/
|
|
3070
3425
|
static extend(newSyncFn, newCacheMax, newCacheBuffer) {
|
|
3071
3426
|
const ParentService = this;
|
|
3072
3427
|
class ChildService extends ParentService {
|
|
3428
|
+
// Intentionally per-subclass — see Service.extend doc.
|
|
3073
3429
|
static _metaList = {};
|
|
3074
3430
|
static _payloadCache = new Cache({
|
|
3075
3431
|
maxSize: newCacheMax || ParentService._cacheMax,
|
|
@@ -3084,18 +3440,34 @@ var Service = class {
|
|
|
3084
3440
|
return ChildService;
|
|
3085
3441
|
}
|
|
3086
3442
|
};
|
|
3443
|
+
var metaJsonCache = /* @__PURE__ */ new WeakMap();
|
|
3444
|
+
function getMetaJson(meta) {
|
|
3445
|
+
let cached = metaJsonCache.get(meta);
|
|
3446
|
+
if (cached === void 0) {
|
|
3447
|
+
cached = JSON.stringify(meta);
|
|
3448
|
+
metaJsonCache.set(meta, cached);
|
|
3449
|
+
}
|
|
3450
|
+
return cached;
|
|
3451
|
+
}
|
|
3087
3452
|
function defaultCacheKey(meta, attrs) {
|
|
3088
|
-
return JSON.stringify(attrs) + SPLITTER +
|
|
3453
|
+
return JSON.stringify(attrs) + SPLITTER + getMetaJson(meta);
|
|
3454
|
+
}
|
|
3455
|
+
function toCacheValue(v) {
|
|
3456
|
+
if (typeof v === "number") return v | 0;
|
|
3457
|
+
if (typeof v === "string") {
|
|
3458
|
+
const n = Number(v);
|
|
3459
|
+
return Number.isFinite(n) ? n | 0 : 0;
|
|
3460
|
+
}
|
|
3461
|
+
return 0;
|
|
3089
3462
|
}
|
|
3090
3463
|
function serviceSend(service, attrs, done, flag, save) {
|
|
3091
|
-
if (service
|
|
3092
|
-
if (service
|
|
3093
|
-
service
|
|
3094
|
-
|
|
3095
|
-
);
|
|
3464
|
+
if (service.destroyed) return;
|
|
3465
|
+
if (service.busy) {
|
|
3466
|
+
const queued = () => serviceSend(service, attrs, done, flag, save);
|
|
3467
|
+
service.enqueue(queued);
|
|
3096
3468
|
return;
|
|
3097
3469
|
}
|
|
3098
|
-
service
|
|
3470
|
+
service.busy = 1;
|
|
3099
3471
|
let attrList;
|
|
3100
3472
|
if (typeof attrs === "string") {
|
|
3101
3473
|
attrList = [{ name: attrs }];
|
|
@@ -3120,10 +3492,10 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3120
3492
|
newPayload = true;
|
|
3121
3493
|
staticEmitter2.fire("done", { payload });
|
|
3122
3494
|
}
|
|
3123
|
-
if (!service
|
|
3495
|
+
if (!service.destroyed) {
|
|
3124
3496
|
const finish = requestCount === total;
|
|
3125
3497
|
if (finish) {
|
|
3126
|
-
service
|
|
3498
|
+
service.busy = 0;
|
|
3127
3499
|
if (flag === FETCH_FLAGS_ALL) {
|
|
3128
3500
|
doneArr[0] = errorArgs;
|
|
3129
3501
|
funcWithTry(done, doneArr, service, noop);
|
|
@@ -3140,10 +3512,7 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3140
3512
|
for (const attr of attrList) {
|
|
3141
3513
|
if (!attr) continue;
|
|
3142
3514
|
const attrObj = typeof attr === "string" ? { name: attr } : attr;
|
|
3143
|
-
const payloadInfo = service.type.get(
|
|
3144
|
-
attrObj,
|
|
3145
|
-
save
|
|
3146
|
-
);
|
|
3515
|
+
const payloadInfo = service.type.get(attrObj, save);
|
|
3147
3516
|
const payloadEntity = payloadInfo.entity;
|
|
3148
3517
|
const cacheKey = payloadEntity.cacheInfo?.key || "";
|
|
3149
3518
|
const complete = remoteComplete.bind(null, requestCount++);
|
|
@@ -3157,15 +3526,13 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3157
3526
|
const cacheComplete = () => {
|
|
3158
3527
|
const list = pendingCacheKeys[cacheKey];
|
|
3159
3528
|
const entity = list.entity;
|
|
3160
|
-
if (entity.cacheInfo) {
|
|
3529
|
+
if (entity instanceof Payload && entity.cacheInfo) {
|
|
3161
3530
|
entity.cacheInfo.time = now();
|
|
3531
|
+
internals.payloadCache.set(cacheKey, entity);
|
|
3162
3532
|
}
|
|
3163
|
-
internals.payloadCache.set(cacheKey, entity);
|
|
3164
3533
|
Reflect.deleteProperty(pendingCacheKeys, cacheKey);
|
|
3165
3534
|
for (const cb of list) {
|
|
3166
|
-
if (typeof cb === "function")
|
|
3167
|
-
cb();
|
|
3168
|
-
}
|
|
3535
|
+
if (typeof cb === "function") cb();
|
|
3169
3536
|
}
|
|
3170
3537
|
};
|
|
3171
3538
|
syncFn(payloadEntity, cacheComplete);
|
|
@@ -3178,12 +3545,14 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3178
3545
|
}
|
|
3179
3546
|
}
|
|
3180
3547
|
|
|
3181
|
-
// src/frame-
|
|
3182
|
-
var
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3548
|
+
// src/frame-visual.ts
|
|
3549
|
+
var FrameVisualBridge = {
|
|
3550
|
+
MSG_PING: "LARK_VIS_PING",
|
|
3551
|
+
MSG_PONG: "LARK_VIS_PONG",
|
|
3552
|
+
MSG_REQUEST_TREE: "LARK_VIS_REQUEST_TREE",
|
|
3553
|
+
MSG_TREE: "LARK_VIS_TREE",
|
|
3554
|
+
MSG_TREE_DELTA: "LARK_VIS_TREE_DELTA"
|
|
3555
|
+
};
|
|
3187
3556
|
function serializeView(view) {
|
|
3188
3557
|
return {
|
|
3189
3558
|
id: view.id,
|
|
@@ -3223,7 +3592,10 @@ function serializeFrame(frameId) {
|
|
|
3223
3592
|
};
|
|
3224
3593
|
}
|
|
3225
3594
|
function serializeFrameTree() {
|
|
3226
|
-
const root = Frame.
|
|
3595
|
+
const root = Frame.getRoot();
|
|
3596
|
+
if (!root) {
|
|
3597
|
+
return { root: null, totalFrames: 0, timestamp: Date.now(), rootId: "" };
|
|
3598
|
+
}
|
|
3227
3599
|
const rootNode = serializeFrame(root.id);
|
|
3228
3600
|
let totalFrames = 0;
|
|
3229
3601
|
const countFrames = (node) => {
|
|
@@ -3251,19 +3623,22 @@ function installFrameVisualizerBridge() {
|
|
|
3251
3623
|
const data = event.data;
|
|
3252
3624
|
if (!data || typeof data !== "object") return;
|
|
3253
3625
|
const type = data.type;
|
|
3254
|
-
if (type === MSG_PING) {
|
|
3626
|
+
if (type === FrameVisualBridge.MSG_PING) {
|
|
3255
3627
|
const source = event.source;
|
|
3256
3628
|
if (source) {
|
|
3257
|
-
source.postMessage(
|
|
3629
|
+
source.postMessage(
|
|
3630
|
+
{ type: FrameVisualBridge.MSG_PONG },
|
|
3631
|
+
{ targetOrigin: "*" }
|
|
3632
|
+
);
|
|
3258
3633
|
}
|
|
3259
3634
|
return;
|
|
3260
3635
|
}
|
|
3261
|
-
if (type === MSG_REQUEST_TREE) {
|
|
3636
|
+
if (type === FrameVisualBridge.MSG_REQUEST_TREE) {
|
|
3262
3637
|
const tree = serializeFrameTree();
|
|
3263
3638
|
const source = event.source;
|
|
3264
3639
|
if (source) {
|
|
3265
3640
|
source.postMessage(
|
|
3266
|
-
{ type: MSG_TREE, data: tree },
|
|
3641
|
+
{ type: FrameVisualBridge.MSG_TREE, data: tree },
|
|
3267
3642
|
{ targetOrigin: "*" }
|
|
3268
3643
|
);
|
|
3269
3644
|
}
|
|
@@ -3282,18 +3657,14 @@ function pushTreeUpdate() {
|
|
|
3282
3657
|
const treeJson = JSON.stringify(tree);
|
|
3283
3658
|
if (treeJson !== lastTreeJson) {
|
|
3284
3659
|
lastTreeJson = treeJson;
|
|
3285
|
-
window.parent.postMessage(
|
|
3660
|
+
window.parent.postMessage(
|
|
3661
|
+
{ type: FrameVisualBridge.MSG_TREE_DELTA, data: tree },
|
|
3662
|
+
"*"
|
|
3663
|
+
);
|
|
3286
3664
|
}
|
|
3287
3665
|
}
|
|
3288
3666
|
|
|
3289
3667
|
// src/framework.ts
|
|
3290
|
-
var config = {
|
|
3291
|
-
rootId: "root",
|
|
3292
|
-
hashbang: "#!",
|
|
3293
|
-
error: (error) => {
|
|
3294
|
-
throw error;
|
|
3295
|
-
}
|
|
3296
|
-
};
|
|
3297
3668
|
var booted3 = false;
|
|
3298
3669
|
var taskList = [];
|
|
3299
3670
|
var taskIndex = 0;
|
|
@@ -3342,6 +3713,9 @@ function task(fn, args, context) {
|
|
|
3342
3713
|
}
|
|
3343
3714
|
}
|
|
3344
3715
|
var dispatcherUpdateTag = 0;
|
|
3716
|
+
function isThenable(value) {
|
|
3717
|
+
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
3718
|
+
}
|
|
3345
3719
|
function viewIsObserveChanged(view) {
|
|
3346
3720
|
const loc = view.locationObserved;
|
|
3347
3721
|
let result = false;
|
|
@@ -3355,7 +3729,7 @@ function viewIsObserveChanged(view) {
|
|
|
3355
3729
|
const changedParams = lastChanged2?.params;
|
|
3356
3730
|
if (changedParams) {
|
|
3357
3731
|
for (const key of loc.keys) {
|
|
3358
|
-
result =
|
|
3732
|
+
result = hasOwnProperty(changedParams, key);
|
|
3359
3733
|
if (result) break;
|
|
3360
3734
|
}
|
|
3361
3735
|
}
|
|
@@ -3367,48 +3741,59 @@ function stateIsObserveChanged(view, stateKeys) {
|
|
|
3367
3741
|
const observedKeys = view.observedStateKeys;
|
|
3368
3742
|
if (!observedKeys) return false;
|
|
3369
3743
|
for (const key of observedKeys) {
|
|
3370
|
-
if (has(
|
|
3744
|
+
if (stateKeys.has(key)) return true;
|
|
3371
3745
|
}
|
|
3372
3746
|
return false;
|
|
3373
3747
|
}
|
|
3374
3748
|
function dispatcherUpdate(frame, stateKeys) {
|
|
3375
|
-
const
|
|
3376
|
-
const
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
view
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3749
|
+
const stack = [frame];
|
|
3750
|
+
const drain = (s) => {
|
|
3751
|
+
while (s.length > 0) {
|
|
3752
|
+
const current = s.pop();
|
|
3753
|
+
const tagged = current;
|
|
3754
|
+
const view = current.view;
|
|
3755
|
+
if (!view || tagged.dispatcherUpdateTag === dispatcherUpdateTag || view.signature <= 1) {
|
|
3756
|
+
continue;
|
|
3757
|
+
}
|
|
3758
|
+
tagged.dispatcherUpdateTag = dispatcherUpdateTag;
|
|
3759
|
+
const isChanged = stateKeys ? stateIsObserveChanged(view, stateKeys) : viewIsObserveChanged(view);
|
|
3760
|
+
let renderPromise;
|
|
3761
|
+
if (isChanged) {
|
|
3762
|
+
const renderResult = funcWithTry(
|
|
3763
|
+
view.renderMethod ?? view.render,
|
|
3764
|
+
[],
|
|
3765
|
+
view,
|
|
3766
|
+
noop
|
|
3767
|
+
);
|
|
3768
|
+
if (isThenable(renderResult)) {
|
|
3769
|
+
renderPromise = renderResult;
|
|
3770
|
+
}
|
|
3771
|
+
}
|
|
3772
|
+
const children = current.children();
|
|
3773
|
+
if (renderPromise) {
|
|
3774
|
+
renderPromise.then(() => {
|
|
3775
|
+
const subStack = [];
|
|
3776
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
3777
|
+
const child = Frame.get(children[i]);
|
|
3778
|
+
if (child) subStack.push(child);
|
|
3779
|
+
}
|
|
3780
|
+
drain(subStack);
|
|
3781
|
+
});
|
|
3782
|
+
} else {
|
|
3783
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
3784
|
+
const child = Frame.get(children[i]);
|
|
3785
|
+
if (child) s.push(child);
|
|
3786
|
+
}
|
|
3400
3787
|
}
|
|
3401
3788
|
}
|
|
3402
3789
|
};
|
|
3403
|
-
|
|
3404
|
-
renderPromise.then(recurse);
|
|
3405
|
-
} else {
|
|
3406
|
-
recurse();
|
|
3407
|
-
}
|
|
3790
|
+
drain(stack);
|
|
3408
3791
|
}
|
|
3409
3792
|
function dispatcherNotifyChange(e) {
|
|
3410
|
-
const rootFrame2 = Frame.
|
|
3411
|
-
|
|
3793
|
+
const rootFrame2 = Frame.getRoot();
|
|
3794
|
+
if (!rootFrame2) return;
|
|
3795
|
+
const routeEvent = e;
|
|
3796
|
+
const view = routeEvent.view;
|
|
3412
3797
|
if (view) {
|
|
3413
3798
|
const viewPath = typeof view === "object" && view !== null ? String(view.to || "") : String(view);
|
|
3414
3799
|
rootFrame2.mountView(viewPath);
|
|
@@ -3425,19 +3810,6 @@ function dispatchEvent(target, eventType, eventInit) {
|
|
|
3425
3810
|
});
|
|
3426
3811
|
target.dispatchEvent(event);
|
|
3427
3812
|
}
|
|
3428
|
-
function use(names, callback) {
|
|
3429
|
-
if (!config.require) {
|
|
3430
|
-
if (callback) callback();
|
|
3431
|
-
return;
|
|
3432
|
-
}
|
|
3433
|
-
const nameList = typeof names === "string" ? [names] : names;
|
|
3434
|
-
const result = config.require(nameList);
|
|
3435
|
-
if (result && typeof result.then === "function") {
|
|
3436
|
-
result.then((modules) => {
|
|
3437
|
-
if (callback) callback(modules);
|
|
3438
|
-
});
|
|
3439
|
-
}
|
|
3440
|
-
}
|
|
3441
3813
|
var WAIT_OK = 1;
|
|
3442
3814
|
var WAIT_TIMEOUT_OR_NOT_FOUND = 0;
|
|
3443
3815
|
function waitZoneViewsRendered(viewId, timeout) {
|
|
@@ -3460,12 +3832,27 @@ function waitZoneViewsRendered(viewId, timeout) {
|
|
|
3460
3832
|
setTimeout(check, 9);
|
|
3461
3833
|
});
|
|
3462
3834
|
}
|
|
3835
|
+
function getConfigImpl(key) {
|
|
3836
|
+
if (key === void 0) return config;
|
|
3837
|
+
return config[key];
|
|
3838
|
+
}
|
|
3463
3839
|
var Framework = {
|
|
3464
3840
|
// ============================================================
|
|
3465
3841
|
// Lifecycle
|
|
3466
3842
|
// ============================================================
|
|
3843
|
+
/** Read framework configuration. See `FrameworkInterface.getConfig`. */
|
|
3844
|
+
getConfig: getConfigImpl,
|
|
3467
3845
|
/**
|
|
3468
|
-
*
|
|
3846
|
+
* Merge a patch into framework configuration. See `FrameworkInterface.setConfig`.
|
|
3847
|
+
*/
|
|
3848
|
+
setConfig(patch) {
|
|
3849
|
+
if (patch && typeof patch === "object") {
|
|
3850
|
+
assign(config, patch);
|
|
3851
|
+
}
|
|
3852
|
+
return config;
|
|
3853
|
+
},
|
|
3854
|
+
/**
|
|
3855
|
+
* @deprecated Use `getConfig()` / `setConfig()`. Behavior unchanged.
|
|
3469
3856
|
*/
|
|
3470
3857
|
config(cfg) {
|
|
3471
3858
|
if (!cfg) {
|
|
@@ -3486,17 +3873,17 @@ var Framework = {
|
|
|
3486
3873
|
}
|
|
3487
3874
|
Router._setConfig(config);
|
|
3488
3875
|
EventDelegator.setFrameGetter((id) => Frame.get(id));
|
|
3489
|
-
Router.on(
|
|
3876
|
+
Router.on(RouterEvents.CHANGED, (data) => {
|
|
3490
3877
|
if (data) dispatcherNotifyChange(data);
|
|
3491
3878
|
});
|
|
3492
|
-
State.on(
|
|
3879
|
+
State.on(RouterEvents.CHANGED, (data) => {
|
|
3493
3880
|
if (data) dispatcherNotifyChange(data);
|
|
3494
3881
|
});
|
|
3495
3882
|
booted3 = true;
|
|
3496
3883
|
markBooted();
|
|
3497
3884
|
markRouterBooted();
|
|
3498
3885
|
installFrameVisualizerBridge();
|
|
3499
|
-
const rootFrame2 = Frame.
|
|
3886
|
+
const rootFrame2 = Frame.createRoot(config.rootId);
|
|
3500
3887
|
Router._bind();
|
|
3501
3888
|
const defaultView = config.defaultView || "";
|
|
3502
3889
|
if (defaultView && !rootFrame2.view) {
|
|
@@ -3551,7 +3938,7 @@ var Framework = {
|
|
|
3551
3938
|
/**
|
|
3552
3939
|
* Check if object has own property.
|
|
3553
3940
|
*/
|
|
3554
|
-
has,
|
|
3941
|
+
has: hasOwnProperty,
|
|
3555
3942
|
/**
|
|
3556
3943
|
* Get object keys.
|
|
3557
3944
|
*/
|
|
@@ -3611,6 +3998,9 @@ if (typeof window !== "undefined") {
|
|
|
3611
3998
|
window.__lark_Router = Router;
|
|
3612
3999
|
window.__lark_Frame = Frame;
|
|
3613
4000
|
window.__lark_View = View;
|
|
4001
|
+
window.__lark_invalidateViewClass = invalidateViewClass;
|
|
4002
|
+
window.__lark_getViewClassRegistry = getViewClassRegistry;
|
|
4003
|
+
window.__lark_registerViewClass = registerViewClass;
|
|
3614
4004
|
}
|
|
3615
4005
|
|
|
3616
4006
|
// src/store.ts
|
|
@@ -3624,28 +4014,38 @@ var Platform = /* @__PURE__ */ ((Platform2) => {
|
|
|
3624
4014
|
var isFunction = (val) => typeof val === "function";
|
|
3625
4015
|
var isObject = (val) => val !== null && typeof val === "object";
|
|
3626
4016
|
var isPromise = (val) => isObject(val) && isFunction(val["then"]);
|
|
3627
|
-
var
|
|
3628
|
-
var
|
|
4017
|
+
var hasOwnProperty2 = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
|
|
4018
|
+
var hasStructuredClone = typeof globalThis !== "undefined" && typeof globalThis.structuredClone === "function";
|
|
4019
|
+
var deepCloneFallback = (obj) => {
|
|
3629
4020
|
if (!obj || !isObject(obj)) return {};
|
|
3630
|
-
const newData = Array.isArray(obj) ? [] :
|
|
4021
|
+
const newData = Array.isArray(obj) ? [] : {};
|
|
3631
4022
|
for (const key in obj) {
|
|
3632
|
-
if (
|
|
4023
|
+
if (hasOwnProperty2(obj, key)) {
|
|
3633
4024
|
const value = obj[key];
|
|
3634
|
-
newData[key] = isObject(value) ?
|
|
4025
|
+
newData[key] = isObject(value) ? deepCloneFallback(value) : value;
|
|
3635
4026
|
}
|
|
3636
4027
|
}
|
|
3637
4028
|
return newData;
|
|
3638
4029
|
};
|
|
4030
|
+
var deepClone = (obj) => {
|
|
4031
|
+
if (hasStructuredClone) {
|
|
4032
|
+
try {
|
|
4033
|
+
return structuredClone(obj);
|
|
4034
|
+
} catch {
|
|
4035
|
+
return deepCloneFallback(obj);
|
|
4036
|
+
}
|
|
4037
|
+
}
|
|
4038
|
+
return deepCloneFallback(obj);
|
|
4039
|
+
};
|
|
3639
4040
|
var cloneData = (data) => isObject(data) ? deepClone(data) : data;
|
|
3640
4041
|
var getDataByKey = (target, key) => {
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
data = rec?.[key];
|
|
4042
|
+
if (!key.includes(".")) {
|
|
4043
|
+
return target[key];
|
|
4044
|
+
}
|
|
4045
|
+
let data = target;
|
|
4046
|
+
for (const k of key.split(".")) {
|
|
4047
|
+
if (!isObject(data)) return void 0;
|
|
4048
|
+
data = data[k];
|
|
3649
4049
|
}
|
|
3650
4050
|
return data;
|
|
3651
4051
|
};
|
|
@@ -3693,17 +4093,18 @@ var Queue = class {
|
|
|
3693
4093
|
};
|
|
3694
4094
|
var addParams2Callback = (cb, params) => {
|
|
3695
4095
|
if (!cb || !params) return;
|
|
3696
|
-
const
|
|
3697
|
-
|
|
3698
|
-
|
|
4096
|
+
const tagged = cb;
|
|
4097
|
+
const existing = tagged.params;
|
|
4098
|
+
if (isObject(existing)) {
|
|
4099
|
+
Object.assign(existing, params);
|
|
3699
4100
|
} else {
|
|
3700
|
-
|
|
4101
|
+
tagged.params = params;
|
|
3701
4102
|
}
|
|
3702
4103
|
};
|
|
3703
4104
|
var runTask = (cb) => {
|
|
3704
|
-
const
|
|
3705
|
-
const params =
|
|
3706
|
-
delete
|
|
4105
|
+
const tagged = cb;
|
|
4106
|
+
const params = tagged.params;
|
|
4107
|
+
delete tagged.params;
|
|
3707
4108
|
try {
|
|
3708
4109
|
cb(params);
|
|
3709
4110
|
} catch {
|
|
@@ -3729,7 +4130,9 @@ var ArrMethods = {};
|
|
|
3729
4130
|
if (res === -1 || res === false) {
|
|
3730
4131
|
res = rawMethod.apply(
|
|
3731
4132
|
this,
|
|
3732
|
-
args.map(
|
|
4133
|
+
args.map(
|
|
4134
|
+
(item) => isObject(item) ? ProxyCache.get(item) ?? item : item
|
|
4135
|
+
)
|
|
3733
4136
|
);
|
|
3734
4137
|
}
|
|
3735
4138
|
return res;
|
|
@@ -3747,6 +4150,7 @@ var inArrUpdate = false;
|
|
|
3747
4150
|
});
|
|
3748
4151
|
function needKeepArrItem(target, newVal, key) {
|
|
3749
4152
|
if (!Array.isArray(target) || !inArrUpdate) return false;
|
|
4153
|
+
if (!isObject(newVal)) return false;
|
|
3750
4154
|
return getLinkKeys(newVal) === createLinkKeys(target, key);
|
|
3751
4155
|
}
|
|
3752
4156
|
var defStateConfig = {
|
|
@@ -3758,13 +4162,13 @@ var StateConfigMap = /* @__PURE__ */ new WeakMap();
|
|
|
3758
4162
|
var setStateConfig = (target, config2) => {
|
|
3759
4163
|
if (target && isObject(config2)) StateConfigMap.set(target, config2);
|
|
3760
4164
|
};
|
|
3761
|
-
|
|
4165
|
+
function getStateConfig(target, key) {
|
|
3762
4166
|
if (!StateConfigMap.has(target)) {
|
|
3763
4167
|
return void 0;
|
|
3764
4168
|
}
|
|
3765
4169
|
const config2 = StateConfigMap.get(target);
|
|
3766
4170
|
return key ? config2?.[key] : config2;
|
|
3767
|
-
}
|
|
4171
|
+
}
|
|
3768
4172
|
var isState = (target) => isObject(target) && StateConfigMap.has(target);
|
|
3769
4173
|
var createLinkKeys = (target, property) => {
|
|
3770
4174
|
if (!hasLinkKeys(target)) return property;
|
|
@@ -3802,7 +4206,7 @@ var needKeep = (key) => {
|
|
|
3802
4206
|
};
|
|
3803
4207
|
var canSetNewVal = (params) => {
|
|
3804
4208
|
const { property, newVal, oldVal } = params;
|
|
3805
|
-
if (
|
|
4209
|
+
if (hasOwnProperty2(params.target, property) && newVal === oldVal)
|
|
3806
4210
|
return false;
|
|
3807
4211
|
return true;
|
|
3808
4212
|
};
|
|
@@ -3814,16 +4218,13 @@ var getNewVal = (params) => {
|
|
|
3814
4218
|
if (config2?.shallow) return newVal;
|
|
3815
4219
|
if (needKeepVal) return newVal;
|
|
3816
4220
|
const linkKeys = createLinkKeys(target, property);
|
|
3817
|
-
const newState = createState(newVal, {
|
|
3818
|
-
...config2,
|
|
3819
|
-
linkKeys
|
|
3820
|
-
});
|
|
4221
|
+
const newState = createState(newVal, { ...config2, linkKeys });
|
|
3821
4222
|
if (isPromise(newVal)) handlePromise(newVal, target, property);
|
|
3822
4223
|
return newState;
|
|
3823
4224
|
};
|
|
3824
4225
|
var genPayload = (params) => {
|
|
3825
4226
|
const { target, property, newVal, oldVal } = params;
|
|
3826
|
-
const config2 = getStateConfig(target)
|
|
4227
|
+
const config2 = getStateConfig(target) ?? defStateConfig;
|
|
3827
4228
|
return {
|
|
3828
4229
|
belong: config2.belong || LARK_GLOBAL,
|
|
3829
4230
|
target,
|
|
@@ -3833,11 +4234,12 @@ var genPayload = (params) => {
|
|
|
3833
4234
|
};
|
|
3834
4235
|
};
|
|
3835
4236
|
var handlePromise = (child, parent, key) => {
|
|
4237
|
+
const childObj = child;
|
|
3836
4238
|
child.then((res) => {
|
|
3837
4239
|
const parentProxy = ProxyCache.get(parent);
|
|
3838
4240
|
if (parentProxy) {
|
|
3839
4241
|
const oldVal = parentProxy[key];
|
|
3840
|
-
if (ProxyCache.get(
|
|
4242
|
+
if (ProxyCache.get(childObj) === oldVal) {
|
|
3841
4243
|
parentProxy[key] = res;
|
|
3842
4244
|
}
|
|
3843
4245
|
}
|
|
@@ -3845,7 +4247,7 @@ var handlePromise = (child, parent, key) => {
|
|
|
3845
4247
|
const parentProxy = ProxyCache.get(parent);
|
|
3846
4248
|
if (parentProxy) {
|
|
3847
4249
|
const oldVal = parentProxy[key];
|
|
3848
|
-
if (ProxyCache.get(
|
|
4250
|
+
if (ProxyCache.get(childObj) === oldVal) {
|
|
3849
4251
|
parentProxy[key] = err;
|
|
3850
4252
|
}
|
|
3851
4253
|
}
|
|
@@ -3857,7 +4259,7 @@ var mark2 = (host, key) => {
|
|
|
3857
4259
|
let sign;
|
|
3858
4260
|
if (!host[_deleteKey]) {
|
|
3859
4261
|
const markHost = host[_markObjKey] || (host[_markObjKey] = {});
|
|
3860
|
-
if (!
|
|
4262
|
+
if (!hasOwnProperty2(markHost, key)) {
|
|
3861
4263
|
markHost[key] = 0;
|
|
3862
4264
|
}
|
|
3863
4265
|
sign = ++markHost[key];
|
|
@@ -3894,7 +4296,7 @@ function createState(initialData, config2) {
|
|
|
3894
4296
|
oldVal
|
|
3895
4297
|
});
|
|
3896
4298
|
if (!canSet) return true;
|
|
3897
|
-
const proxyTarget = receiver
|
|
4299
|
+
const proxyTarget = isObject(receiver) && receiver !== null ? receiver : state;
|
|
3898
4300
|
newVal = getNewVal({
|
|
3899
4301
|
target: proxyTarget,
|
|
3900
4302
|
property: strProp,
|
|
@@ -3914,7 +4316,7 @@ function createState(initialData, config2) {
|
|
|
3914
4316
|
},
|
|
3915
4317
|
deleteProperty(target, property) {
|
|
3916
4318
|
const strProp = property;
|
|
3917
|
-
if (!
|
|
4319
|
+
if (!hasOwnProperty2(target, strProp)) return true;
|
|
3918
4320
|
const oldVal = Reflect.get(target, property);
|
|
3919
4321
|
Reflect.deleteProperty(target, property);
|
|
3920
4322
|
const payload = genPayload({
|
|
@@ -3958,11 +4360,8 @@ function shallowSet(target, key, data) {
|
|
|
3958
4360
|
keep(key);
|
|
3959
4361
|
const config2 = getStateConfig(target);
|
|
3960
4362
|
const linkKeys = createLinkKeys(target, key);
|
|
3961
|
-
target[key] = createState(data, {
|
|
3962
|
-
|
|
3963
|
-
linkKeys,
|
|
3964
|
-
shallow: true
|
|
3965
|
-
});
|
|
4363
|
+
target[key] = createState(data, { ...config2, linkKeys, shallow: true });
|
|
4364
|
+
return target[key];
|
|
3966
4365
|
}
|
|
3967
4366
|
var GlobalDeps = /* @__PURE__ */ new Map();
|
|
3968
4367
|
function track(payload) {
|
|
@@ -4043,8 +4442,22 @@ var _stateKeys = /* @__PURE__ */ Symbol("state-keys");
|
|
|
4043
4442
|
var _storeState = /* @__PURE__ */ Symbol("store-state");
|
|
4044
4443
|
var _storeDefScheduler = /* @__PURE__ */ Symbol("store-def-scheduler");
|
|
4045
4444
|
var _storeProxy = /* @__PURE__ */ Symbol("fn:store-proxy");
|
|
4445
|
+
var _computedKeys = /* @__PURE__ */ Symbol("store-computed-keys");
|
|
4446
|
+
var COMPUTED_BRAND = /* @__PURE__ */ Symbol("store-computed-brand");
|
|
4447
|
+
function computed(deps, fn) {
|
|
4448
|
+
const marker = {
|
|
4449
|
+
[COMPUTED_BRAND]: true,
|
|
4450
|
+
deps,
|
|
4451
|
+
fn
|
|
4452
|
+
};
|
|
4453
|
+
return marker;
|
|
4454
|
+
}
|
|
4455
|
+
function isComputedMarker(val) {
|
|
4456
|
+
return isObject(val) && val[COMPUTED_BRAND] === true;
|
|
4457
|
+
}
|
|
4046
4458
|
var BaseStore = class {
|
|
4047
4459
|
[_storeStatus] = 0 /* BEFORE_CREATE */;
|
|
4460
|
+
[_computedKeys] = /* @__PURE__ */ new Set();
|
|
4048
4461
|
[_storeDefScheduler] = getDefScheduler;
|
|
4049
4462
|
[_storeBoot]() {
|
|
4050
4463
|
this[_storeStatus] = 2 /* ACTIVE */;
|
|
@@ -4067,10 +4480,16 @@ var BaseStore = class {
|
|
|
4067
4480
|
if (isObject(body)) {
|
|
4068
4481
|
const state = {};
|
|
4069
4482
|
const handlers = {};
|
|
4483
|
+
const computedDefs = {};
|
|
4484
|
+
const computedKeys = this[_computedKeys];
|
|
4070
4485
|
Reflect.ownKeys(body).forEach((key) => {
|
|
4071
4486
|
const strKey = key;
|
|
4072
4487
|
const val = body[strKey];
|
|
4073
|
-
if (
|
|
4488
|
+
if (isComputedMarker(val)) {
|
|
4489
|
+
computedDefs[strKey] = val;
|
|
4490
|
+
state[strKey] = void 0;
|
|
4491
|
+
computedKeys.add(strKey);
|
|
4492
|
+
} else if (isFunction(val)) {
|
|
4074
4493
|
if (!excludeFns.includes(strKey)) handlers[strKey] = val;
|
|
4075
4494
|
} else {
|
|
4076
4495
|
state[strKey] = val;
|
|
@@ -4080,6 +4499,22 @@ var BaseStore = class {
|
|
|
4080
4499
|
this[_originState] = cloneData(state);
|
|
4081
4500
|
this[_stateKeys] = Object.keys(state);
|
|
4082
4501
|
this[_storeState] = createState(state, { belong: this[_storeName] });
|
|
4502
|
+
if (Object.keys(computedDefs).length > 0) {
|
|
4503
|
+
const belong = this[_storeName];
|
|
4504
|
+
const storeState = this[_storeState];
|
|
4505
|
+
for (const key of Object.keys(computedDefs)) {
|
|
4506
|
+
const def = computedDefs[key];
|
|
4507
|
+
const recompute = () => {
|
|
4508
|
+
storeState[key] = def.fn();
|
|
4509
|
+
};
|
|
4510
|
+
recompute();
|
|
4511
|
+
const trackList = def.deps.map((depKey) => ({
|
|
4512
|
+
key: depKey,
|
|
4513
|
+
cb: recompute
|
|
4514
|
+
}));
|
|
4515
|
+
if (trackList.length > 0) track({ belong, trackList });
|
|
4516
|
+
}
|
|
4517
|
+
}
|
|
4083
4518
|
}
|
|
4084
4519
|
}
|
|
4085
4520
|
constructor(name, config2) {
|
|
@@ -4101,18 +4536,21 @@ var BaseStore = class {
|
|
|
4101
4536
|
}
|
|
4102
4537
|
[_storeProxy](toOut = false) {
|
|
4103
4538
|
const self = this;
|
|
4104
|
-
|
|
4539
|
+
const proxy = new Proxy(self, {
|
|
4105
4540
|
get(target, property) {
|
|
4106
|
-
|
|
4107
|
-
|
|
4541
|
+
const strProp = property;
|
|
4542
|
+
if (self[_stateKeys].includes(strProp)) {
|
|
4543
|
+
const val = self[_storeState][strProp];
|
|
4108
4544
|
return toOut ? cloneData(val) : val;
|
|
4109
4545
|
}
|
|
4110
4546
|
return Reflect.get(target, property);
|
|
4111
4547
|
},
|
|
4112
4548
|
set(_target, property, val) {
|
|
4113
4549
|
if (toOut) return true;
|
|
4114
|
-
|
|
4115
|
-
|
|
4550
|
+
const strProp = property;
|
|
4551
|
+
if (self[_computedKeys].has(strProp)) return true;
|
|
4552
|
+
if (self[_stateKeys].includes(strProp)) {
|
|
4553
|
+
self[_storeState][strProp] = val;
|
|
4116
4554
|
}
|
|
4117
4555
|
return true;
|
|
4118
4556
|
},
|
|
@@ -4120,11 +4558,14 @@ var BaseStore = class {
|
|
|
4120
4558
|
return Reflect.has(target, property) || self[_stateKeys].includes(property);
|
|
4121
4559
|
}
|
|
4122
4560
|
});
|
|
4561
|
+
return proxy;
|
|
4123
4562
|
}
|
|
4124
4563
|
};
|
|
4125
4564
|
var LarkUtils = {
|
|
4126
4565
|
isLarkView(instance) {
|
|
4127
|
-
|
|
4566
|
+
if (!isObject(instance)) return false;
|
|
4567
|
+
const updater = instance["updater"];
|
|
4568
|
+
return isObject(updater) && isFunction(updater["set"]) && isFunction(updater["digest"]);
|
|
4128
4569
|
},
|
|
4129
4570
|
getRender(view) {
|
|
4130
4571
|
return view.updater.digest.bind(view.updater);
|
|
@@ -4140,41 +4581,45 @@ var getLarkAdapter = (storeName) => ({
|
|
|
4140
4581
|
Store: LarkStore,
|
|
4141
4582
|
useStore: ((view) => {
|
|
4142
4583
|
const store = getStore(storeName);
|
|
4584
|
+
if (!(store instanceof LarkStore)) return {};
|
|
4143
4585
|
return store[_storeBoot](view);
|
|
4144
4586
|
})
|
|
4145
4587
|
});
|
|
4146
|
-
var
|
|
4147
|
-
var
|
|
4588
|
+
var _innerObserveFlags = /* @__PURE__ */ Symbol("store-inner-observe-flags");
|
|
4589
|
+
var _boundViews = /* @__PURE__ */ Symbol("store-bound-views");
|
|
4148
4590
|
var LarkStore = class extends BaseStore {
|
|
4149
|
-
[
|
|
4150
|
-
[
|
|
4591
|
+
[_boundViews] = /* @__PURE__ */ new Set();
|
|
4592
|
+
[_innerObserveFlags] = /* @__PURE__ */ new Set();
|
|
4151
4593
|
[_storeBoot](view) {
|
|
4152
|
-
if (view && LarkUtils.isLarkView(view) && !this[
|
|
4153
|
-
this[
|
|
4594
|
+
if (view && LarkUtils.isLarkView(view) && !this[_boundViews].has(view)) {
|
|
4595
|
+
this[_boundViews].add(view);
|
|
4154
4596
|
LarkUtils.onDestroy(view, () => {
|
|
4155
|
-
this[
|
|
4597
|
+
this[_boundViews].delete(view);
|
|
4156
4598
|
});
|
|
4157
4599
|
}
|
|
4158
4600
|
return super[_storeBoot]();
|
|
4159
4601
|
}
|
|
4160
4602
|
[_storeDestroy]() {
|
|
4161
|
-
this[
|
|
4162
|
-
this[
|
|
4603
|
+
this[_boundViews].clear();
|
|
4604
|
+
this[_innerObserveFlags].clear();
|
|
4163
4605
|
super[_storeDestroy]();
|
|
4164
4606
|
}
|
|
4165
4607
|
observe(view, keys2, defCallback) {
|
|
4166
4608
|
if (this[_storeStatus] !== 2 /* ACTIVE */) return noop;
|
|
4167
|
-
let observeKeys = keys2;
|
|
4609
|
+
let observeKeys = Array.isArray(keys2) ? keys2 : [];
|
|
4168
4610
|
const _view = view;
|
|
4169
4611
|
const renderFn = _view ? LarkUtils.getRender(_view) : noop;
|
|
4170
4612
|
const dateSetterFn = _view ? LarkUtils.getDataSetter(_view) : noop;
|
|
4171
4613
|
const isInnerObserve = !view;
|
|
4172
4614
|
const innerFlags = /* @__PURE__ */ new Set();
|
|
4173
|
-
const storeInnerObserveFlags = this[
|
|
4615
|
+
const storeInnerObserveFlags = this[_innerObserveFlags];
|
|
4174
4616
|
if (isFunction(keys2)) {
|
|
4175
4617
|
const res = keys2();
|
|
4176
4618
|
if (Array.isArray(res)) observeKeys = res;
|
|
4177
4619
|
}
|
|
4620
|
+
if (keys2 === void 0 && _view && observeKeys.length === 0 && Array.isArray(this[_stateKeys])) {
|
|
4621
|
+
observeKeys = this[_stateKeys].slice();
|
|
4622
|
+
}
|
|
4178
4623
|
const defSetter = (immediate, key, alias, transform) => () => {
|
|
4179
4624
|
const stateVal = getDataByKey(this, key);
|
|
4180
4625
|
let data = { [alias || key]: stateVal };
|
|
@@ -4229,11 +4674,12 @@ var getReactAdapter = (storeName) => ({
|
|
|
4229
4674
|
Store: ReactStore,
|
|
4230
4675
|
useStore: (() => {
|
|
4231
4676
|
const store = getStore(storeName);
|
|
4677
|
+
if (!(store instanceof ReactStore)) return {};
|
|
4232
4678
|
return store[_storeBoot]();
|
|
4233
4679
|
})
|
|
4234
4680
|
});
|
|
4235
|
-
var
|
|
4236
|
-
var
|
|
4681
|
+
var _observe = /* @__PURE__ */ Symbol("store-observe");
|
|
4682
|
+
var _getLastState = /* @__PURE__ */ Symbol("store-get-last-state");
|
|
4237
4683
|
var ReactStore = class extends BaseStore {
|
|
4238
4684
|
stateChangeCount = 0;
|
|
4239
4685
|
lastCount = 0;
|
|
@@ -4247,7 +4693,7 @@ var ReactStore = class extends BaseStore {
|
|
|
4247
4693
|
}
|
|
4248
4694
|
[_storeCreate](body) {
|
|
4249
4695
|
super[_storeCreate](body);
|
|
4250
|
-
this[
|
|
4696
|
+
this[_observe](() => {
|
|
4251
4697
|
this.stateChangeCount += 1;
|
|
4252
4698
|
});
|
|
4253
4699
|
}
|
|
@@ -4257,7 +4703,7 @@ var ReactStore = class extends BaseStore {
|
|
|
4257
4703
|
this.lastCount = currCount;
|
|
4258
4704
|
return changed;
|
|
4259
4705
|
}
|
|
4260
|
-
[
|
|
4706
|
+
[_getLastState](handlers) {
|
|
4261
4707
|
if (this.isStateChanged() || !this.lastState) {
|
|
4262
4708
|
const state = this[_storeState];
|
|
4263
4709
|
const immutableState = freezeData(state);
|
|
@@ -4265,7 +4711,7 @@ var ReactStore = class extends BaseStore {
|
|
|
4265
4711
|
}
|
|
4266
4712
|
return this.lastState;
|
|
4267
4713
|
}
|
|
4268
|
-
[
|
|
4714
|
+
[_observe](cb) {
|
|
4269
4715
|
const tasks = this[_stateKeys].map((key) => ({ key, cb }));
|
|
4270
4716
|
track({ belong: this[_storeName], trackList: tasks });
|
|
4271
4717
|
return () => clear({ belong: this[_storeName], clearList: tasks });
|
|
@@ -4292,6 +4738,7 @@ var getNodeAdapter = (storeName) => ({
|
|
|
4292
4738
|
Store: NodeStore,
|
|
4293
4739
|
useStore: (() => {
|
|
4294
4740
|
const store = getStore(storeName);
|
|
4741
|
+
if (!(store instanceof NodeStore)) return {};
|
|
4295
4742
|
return store[_storeBoot]();
|
|
4296
4743
|
})
|
|
4297
4744
|
});
|
|
@@ -4318,7 +4765,7 @@ var getPlatform = (comp) => {
|
|
|
4318
4765
|
if (LarkUtils.isLarkView(comp)) return "lark" /* Lark */;
|
|
4319
4766
|
return void 0;
|
|
4320
4767
|
};
|
|
4321
|
-
var extendApis = { lazySet, shallowSet };
|
|
4768
|
+
var extendApis = { lazySet, shallowSet, computed };
|
|
4322
4769
|
var StoreCache = /* @__PURE__ */ new Map();
|
|
4323
4770
|
function defineStore(name, creator, config2) {
|
|
4324
4771
|
if (StoreCache.has(name)) {
|
|
@@ -4329,15 +4776,20 @@ function defineStore(name, creator, config2) {
|
|
|
4329
4776
|
const StoreClass = adapter.Store;
|
|
4330
4777
|
const useStore = adapter.useStore;
|
|
4331
4778
|
const store = new StoreClass(name, config2);
|
|
4332
|
-
store[
|
|
4333
|
-
|
|
4334
|
-
);
|
|
4779
|
+
const innerProxy = store[_innerStore]();
|
|
4780
|
+
const body = creator(innerProxy, extendApis);
|
|
4781
|
+
store[_storeCreate](body);
|
|
4335
4782
|
Object.defineProperties(useStore, {
|
|
4336
4783
|
$storeName: { value: name, configurable: true },
|
|
4337
4784
|
$destroyFn: { value: () => store[_storeDestroy](), configurable: true }
|
|
4338
4785
|
});
|
|
4339
4786
|
if (!StoreCache.has(name)) {
|
|
4340
|
-
StoreCache.set(name, {
|
|
4787
|
+
StoreCache.set(name, {
|
|
4788
|
+
store,
|
|
4789
|
+
creator,
|
|
4790
|
+
config: config2,
|
|
4791
|
+
useStore
|
|
4792
|
+
});
|
|
4341
4793
|
}
|
|
4342
4794
|
return useStore;
|
|
4343
4795
|
}
|
|
@@ -4359,7 +4811,7 @@ function getUseStore(name) {
|
|
|
4359
4811
|
return void 0;
|
|
4360
4812
|
}
|
|
4361
4813
|
function cloneStore(name, useStore, config2) {
|
|
4362
|
-
const oldStoreName = useStore
|
|
4814
|
+
const oldStoreName = useStore.$storeName ?? "";
|
|
4363
4815
|
const cached = StoreCache.get(oldStoreName);
|
|
4364
4816
|
const oldStoreCreator = cached?.creator;
|
|
4365
4817
|
const oldConfig = cached?.config || {};
|
|
@@ -4380,16 +4832,12 @@ function isStoreActive(name) {
|
|
|
4380
4832
|
}
|
|
4381
4833
|
var cellCount = 0;
|
|
4382
4834
|
function cell(data) {
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
linkKeys: `${LARK_GLOBAL}_${cellCount++}`
|
|
4386
|
-
});
|
|
4835
|
+
const linkKeys = `${LARK_GLOBAL}_${cellCount++}`;
|
|
4836
|
+
return createState(data, { belong: LARK_GLOBAL, linkKeys });
|
|
4387
4837
|
}
|
|
4388
4838
|
function observeCell(state, cb, immediate = true) {
|
|
4389
4839
|
const linkKeys = getLinkKeys(state);
|
|
4390
|
-
if (!linkKeys)
|
|
4391
|
-
return () => {
|
|
4392
|
-
};
|
|
4840
|
+
if (!linkKeys) return noop;
|
|
4393
4841
|
const keys2 = linkKeys.split(".");
|
|
4394
4842
|
const key = keys2[keys2.length - 1];
|
|
4395
4843
|
const list = [{ key, cb }];
|
|
@@ -4398,30 +4846,32 @@ function observeCell(state, cb, immediate = true) {
|
|
|
4398
4846
|
return () => clear({ belong: LARK_GLOBAL, clearList: list });
|
|
4399
4847
|
}
|
|
4400
4848
|
function multi(useStore) {
|
|
4401
|
-
const storeName = useStore
|
|
4849
|
+
const storeName = useStore.$storeName ?? "";
|
|
4402
4850
|
const flagSym = `lark-comp-${storeName}`;
|
|
4403
4851
|
const map = /* @__PURE__ */ new Map();
|
|
4404
4852
|
let rootViewPath;
|
|
4405
4853
|
const getFlag = (viewContext) => {
|
|
4406
|
-
const owner = viewContext
|
|
4407
|
-
const viewPath = owner?.
|
|
4408
|
-
const viewId = owner?.
|
|
4854
|
+
const owner = viewContext.owner;
|
|
4855
|
+
const viewPath = owner?.path ?? "";
|
|
4856
|
+
const viewId = owner?.id ?? "";
|
|
4409
4857
|
let flag;
|
|
4410
4858
|
if (viewPath === rootViewPath) {
|
|
4411
4859
|
flag = `${flagSym}-${viewId}`;
|
|
4412
4860
|
} else {
|
|
4413
|
-
|
|
4861
|
+
const initParams = owner?.viewInitParams;
|
|
4862
|
+
const candidate = initParams?.[flagSym];
|
|
4863
|
+
flag = typeof candidate === "string" ? candidate : void 0;
|
|
4414
4864
|
}
|
|
4415
|
-
if (owner && isFunction(owner
|
|
4416
|
-
const rawMountFrame = owner
|
|
4417
|
-
owner
|
|
4865
|
+
if (owner && isFunction(owner.mountFrame)) {
|
|
4866
|
+
const rawMountFrame = owner.mountFrame;
|
|
4867
|
+
owner.mountFrame = (frameId, viewPath2, viewInitParams = {}) => rawMountFrame.call(
|
|
4418
4868
|
owner,
|
|
4419
|
-
|
|
4869
|
+
frameId,
|
|
4420
4870
|
viewPath2,
|
|
4421
4871
|
Object.assign(viewInitParams, { [flagSym]: flag })
|
|
4422
4872
|
);
|
|
4423
4873
|
}
|
|
4424
|
-
return flag;
|
|
4874
|
+
return flag ?? "";
|
|
4425
4875
|
};
|
|
4426
4876
|
const useFn = ((view) => {
|
|
4427
4877
|
if (!view)
|
|
@@ -4429,7 +4879,8 @@ function multi(useStore) {
|
|
|
4429
4879
|
"[@lark.js/mvc error] multi: cannot find the view instance"
|
|
4430
4880
|
);
|
|
4431
4881
|
const viewCtx = view;
|
|
4432
|
-
const
|
|
4882
|
+
const tag = viewCtx[flagSym];
|
|
4883
|
+
const flag = typeof tag === "string" ? tag : "";
|
|
4433
4884
|
if (map.has(flag)) return map.get(flag);
|
|
4434
4885
|
const newFn = cloneStore(flag, useStore);
|
|
4435
4886
|
map.set(flag, newFn);
|
|
@@ -4438,8 +4889,7 @@ function multi(useStore) {
|
|
|
4438
4889
|
const mixinObj = {
|
|
4439
4890
|
make() {
|
|
4440
4891
|
if (!rootViewPath) {
|
|
4441
|
-
|
|
4442
|
-
rootViewPath = owner?.["path"] || "";
|
|
4892
|
+
rootViewPath = this.owner?.path ?? "";
|
|
4443
4893
|
}
|
|
4444
4894
|
this[flagSym] = getFlag(this);
|
|
4445
4895
|
}
|
|
@@ -4646,7 +5096,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
4646
5096
|
return `${debugPrefix}<%for(${forExpr}){%>`;
|
|
4647
5097
|
}
|
|
4648
5098
|
const tokens = code.split(/\s+/);
|
|
4649
|
-
const keyword = tokens.shift();
|
|
5099
|
+
const keyword = tokens.shift() ?? "";
|
|
4650
5100
|
switch (keyword) {
|
|
4651
5101
|
case "if": {
|
|
4652
5102
|
blockStack.push({ ctrl: "if", line: lineNo });
|
|
@@ -4870,13 +5320,9 @@ function compileToFunction(source, debug, file) {
|
|
|
4870
5320
|
}
|
|
4871
5321
|
const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
|
|
4872
5322
|
funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
|
|
4873
|
-
|
|
4874
|
-
const encode = `if(!$strSafe){let $entMap={'&':'amp','<':'lt','>':'gt','"':'#34','\\'':'#39','\`':'#96'},$entReg=/[&<>"'\`]/g,$entFn=m=>'&'+$entMap[m]+';';$strSafe=v=>''+(v==null?'':v);$encHtml=v=>$strSafe(v).replace($entReg,$entFn)}`;
|
|
4875
|
-
const encodeURIMore = `if(!$encUri){let $uriMap={'!':'%21','\\'':'%27','(':'%28',')':'%29','*':'%2A'},$uriFn=m=>$uriMap[m],$uriReg=/[!')(*]/g;$encUri=v=>encodeURIComponent($strSafe(v)).replace($uriReg,$uriFn)}`;
|
|
4876
|
-
const encodeQuote = `if(!$encQuote){let $qReg=/['"\\\\]/g;$encQuote=v=>$strSafe(v).replace($qReg,'\\\\$&')}`;
|
|
5323
|
+
void hasAtRule;
|
|
4877
5324
|
const refFallback = "if(!$refAlt)$refAlt=$data;";
|
|
4878
|
-
const
|
|
4879
|
-
const fullSource = `${fns}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
|
|
5325
|
+
const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
|
|
4880
5326
|
return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
|
|
4881
5327
|
}
|
|
4882
5328
|
function compileTemplate(source, options = {}) {
|
|
@@ -4888,15 +5334,12 @@ function compileTemplate(source, options = {}) {
|
|
|
4888
5334
|
const funcBody = compileToFunction(finalSource, debug, file);
|
|
4889
5335
|
const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
|
|
4890
5336
|
const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
|
|
4891
|
-
return `
|
|
5337
|
+
return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
|
|
5338
|
+
export default function(data, viewId, refData) {
|
|
4892
5339
|
let $data = data || {},
|
|
4893
|
-
$viewId =
|
|
5340
|
+
$viewId = viewId || '';
|
|
4894
5341
|
return (${funcWithVars})($data, $viewId, refData,
|
|
4895
|
-
|
|
4896
|
-
/* $strSafe */ v => String(v == null ? '' : v),
|
|
4897
|
-
/* $encUri */ null,
|
|
4898
|
-
/* $refFn */ null,
|
|
4899
|
-
/* $encQuote */ null
|
|
5342
|
+
__larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
|
|
4900
5343
|
);
|
|
4901
5344
|
}`;
|
|
4902
5345
|
}
|
|
@@ -5021,31 +5464,37 @@ function walkAst(ast, visitors) {
|
|
|
5021
5464
|
if (visitors[type]) {
|
|
5022
5465
|
visitors[type](node);
|
|
5023
5466
|
}
|
|
5467
|
+
const bag = node;
|
|
5024
5468
|
for (const key of Object.keys(node)) {
|
|
5025
5469
|
if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
|
|
5026
5470
|
continue;
|
|
5027
|
-
if (type === "MemberExpression" && key === "property"
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
continue;
|
|
5471
|
+
if (type === "MemberExpression" && key === "property") {
|
|
5472
|
+
const me = node;
|
|
5473
|
+
if (!me.computed) continue;
|
|
5031
5474
|
}
|
|
5032
|
-
if (type === "
|
|
5033
|
-
|
|
5475
|
+
if (type === "ObjectProperty" && key === "key") {
|
|
5476
|
+
const op = node;
|
|
5477
|
+
if (!op.computed) continue;
|
|
5034
5478
|
}
|
|
5035
|
-
|
|
5479
|
+
if (type === "ObjectMethod" && key === "key") {
|
|
5480
|
+
const om = node;
|
|
5481
|
+
if (!om.computed) continue;
|
|
5482
|
+
}
|
|
5483
|
+
const child = bag[key];
|
|
5036
5484
|
if (Array.isArray(child)) {
|
|
5037
5485
|
for (const item of child) {
|
|
5038
|
-
if (item
|
|
5039
|
-
visit(item);
|
|
5040
|
-
}
|
|
5486
|
+
if (isAstNode(item)) visit(item);
|
|
5041
5487
|
}
|
|
5042
|
-
} else if (child
|
|
5488
|
+
} else if (isAstNode(child)) {
|
|
5043
5489
|
visit(child);
|
|
5044
5490
|
}
|
|
5045
5491
|
}
|
|
5046
5492
|
}
|
|
5047
5493
|
visit(ast);
|
|
5048
5494
|
}
|
|
5495
|
+
function isAstNode(v) {
|
|
5496
|
+
return !!v && typeof v === "object" && typeof v.type === "string";
|
|
5497
|
+
}
|
|
5049
5498
|
var BUILTIN_GLOBALS = {
|
|
5050
5499
|
// ─── Template runtime helpers (injected by compileToFunction) ───────
|
|
5051
5500
|
//
|
|
@@ -5199,15 +5648,17 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
|
|
|
5199
5648
|
export {
|
|
5200
5649
|
CALL_BREAK_TIME,
|
|
5201
5650
|
Cache,
|
|
5651
|
+
cross_site_default as CrossSite,
|
|
5202
5652
|
EVENT_METHOD_REGEXP,
|
|
5203
5653
|
EventDelegator,
|
|
5204
5654
|
EventEmitter,
|
|
5205
5655
|
Frame,
|
|
5656
|
+
FrameVisualBridge,
|
|
5206
5657
|
Framework,
|
|
5207
5658
|
LARK_VIEW,
|
|
5208
5659
|
Payload,
|
|
5209
5660
|
Platform,
|
|
5210
|
-
ROUTER_EVENTS,
|
|
5661
|
+
RouterEvents as ROUTER_EVENTS,
|
|
5211
5662
|
Router,
|
|
5212
5663
|
SPLITTER,
|
|
5213
5664
|
Service,
|
|
@@ -5221,13 +5672,14 @@ export {
|
|
|
5221
5672
|
applyVdomOps,
|
|
5222
5673
|
assign,
|
|
5223
5674
|
cell,
|
|
5224
|
-
classExtend,
|
|
5225
5675
|
cloneData,
|
|
5226
5676
|
cloneStore,
|
|
5227
5677
|
compileTemplate,
|
|
5678
|
+
computed,
|
|
5228
5679
|
createState,
|
|
5229
5680
|
createVdomRef,
|
|
5230
5681
|
defineStore,
|
|
5682
|
+
defineView,
|
|
5231
5683
|
delStore,
|
|
5232
5684
|
encodeHTML,
|
|
5233
5685
|
encodeQ,
|
|
@@ -5235,6 +5687,7 @@ export {
|
|
|
5235
5687
|
encodeURIExtra,
|
|
5236
5688
|
ensureElementId,
|
|
5237
5689
|
extractGlobalVars,
|
|
5690
|
+
config as frameworkConfig,
|
|
5238
5691
|
funcWithTry,
|
|
5239
5692
|
generateId,
|
|
5240
5693
|
getAttribute,
|
|
@@ -5242,8 +5695,9 @@ export {
|
|
|
5242
5695
|
getPlatform,
|
|
5243
5696
|
getStore,
|
|
5244
5697
|
getUseStore,
|
|
5245
|
-
|
|
5698
|
+
hasOwnProperty,
|
|
5246
5699
|
installFrameVisualizerBridge,
|
|
5700
|
+
invalidateViewClass,
|
|
5247
5701
|
isPlainObject,
|
|
5248
5702
|
isPrimitive,
|
|
5249
5703
|
isPrimitiveOrFunc,
|
|
@@ -5262,6 +5716,7 @@ export {
|
|
|
5262
5716
|
observeCell,
|
|
5263
5717
|
parseUri,
|
|
5264
5718
|
registerViewClass,
|
|
5719
|
+
resetProjectsMap,
|
|
5265
5720
|
safeguard,
|
|
5266
5721
|
serializeFrameTree,
|
|
5267
5722
|
setData,
|
|
@@ -5273,6 +5728,7 @@ export {
|
|
|
5273
5728
|
toUri,
|
|
5274
5729
|
translateData,
|
|
5275
5730
|
unmark,
|
|
5731
|
+
use,
|
|
5276
5732
|
vdomGetCompareKey,
|
|
5277
5733
|
vdomGetNode,
|
|
5278
5734
|
vdomSetAttributes,
|