@lark.js/mvc 0.0.4 → 0.0.6
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 +770 -506
- package/dist/{chunk-ANWA22AX.js → chunk-3HSA7OHB.js} +30 -31
- package/dist/index.cjs +1107 -1343
- package/dist/index.d.cts +618 -257
- package/dist/index.d.ts +618 -257
- package/dist/index.js +1094 -1324
- 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 +30 -31
- package/dist/vite.d.cts +3 -3
- package/dist/vite.d.ts +3 -3
- package/dist/vite.js +1 -1
- package/dist/webpack.cjs +30 -31
- package/dist/webpack.js +1 -1
- package/package.json +41 -27
- package/src/client.d.ts +81 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/constants.ts
|
|
2
2
|
var globalCounter = 0;
|
|
3
|
-
var SPLITTER =
|
|
4
|
-
var
|
|
3
|
+
var SPLITTER = String.fromCharCode(30);
|
|
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
|
|
@@ -301,7 +305,7 @@ function safeguard(data, getter, setter, isRoot) {
|
|
|
301
305
|
set(target, property, value) {
|
|
302
306
|
if (!setter && !prefix) {
|
|
303
307
|
throw new Error(
|
|
304
|
-
"Avoid write back, key: " + prefix + property + " value:" + value + " more: https://github.com/hangtiancheng/
|
|
308
|
+
"Avoid write back, key: " + prefix + property + " value:" + value + " more: https://github.com/hangtiancheng/lark"
|
|
305
309
|
);
|
|
306
310
|
}
|
|
307
311
|
Reflect.set(target, property, value);
|
|
@@ -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;
|
|
455
468
|
}
|
|
456
|
-
|
|
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);
|
|
487
|
+
}
|
|
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);
|
|
490
528
|
break;
|
|
491
529
|
}
|
|
492
530
|
}
|
|
531
|
+
} else {
|
|
532
|
+
for (let i = 0; i < list.length; i++) {
|
|
533
|
+
if (list[i].handler === handler) {
|
|
534
|
+
list.splice(i, 1);
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
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,8 @@ var cachedDefaultPath;
|
|
|
746
767
|
var cachedRewrite;
|
|
747
768
|
var defaultTitle;
|
|
748
769
|
var frameworkConfig;
|
|
770
|
+
var routeMode = "history";
|
|
771
|
+
var beforeEachGuards = [];
|
|
749
772
|
function createEmptyLocation() {
|
|
750
773
|
return {
|
|
751
774
|
href: "",
|
|
@@ -770,7 +793,8 @@ function attachViewAndPath(loc) {
|
|
|
770
793
|
cachedRewrite = frameworkConfig.rewrite;
|
|
771
794
|
}
|
|
772
795
|
if (!loc.view) {
|
|
773
|
-
|
|
796
|
+
const rawPath = routeMode === "history" ? loc.query["path"] || loc.hash["path"] : loc.hash["path"];
|
|
797
|
+
let path = rawPath || cachedDefaultPath || "/";
|
|
774
798
|
if (cachedRewrite) {
|
|
775
799
|
path = cachedRewrite(
|
|
776
800
|
path,
|
|
@@ -836,7 +860,16 @@ function getChanged(oldLoc, newLoc) {
|
|
|
836
860
|
changedCache.set(tKey, finalResult);
|
|
837
861
|
return finalResult;
|
|
838
862
|
}
|
|
839
|
-
function
|
|
863
|
+
function updateBrowserUrl(path, replace) {
|
|
864
|
+
if (routeMode === "history") {
|
|
865
|
+
const url = path || "/";
|
|
866
|
+
if (replace) {
|
|
867
|
+
window.history.replaceState(null, "", url);
|
|
868
|
+
} else {
|
|
869
|
+
window.history.pushState(null, "", url);
|
|
870
|
+
}
|
|
871
|
+
return;
|
|
872
|
+
}
|
|
840
873
|
const hashbang = frameworkConfig?.hashbang || "#!";
|
|
841
874
|
const fullPath = path === "" ? "" : hashbang + path;
|
|
842
875
|
if (replace) {
|
|
@@ -847,9 +880,10 @@ function updateHash(path, replace) {
|
|
|
847
880
|
}
|
|
848
881
|
function updateUrl(path, params, loc, replace, silentFlag, lQuery) {
|
|
849
882
|
path = toUri(path, params, lQuery);
|
|
850
|
-
|
|
883
|
+
const currentSrc = routeMode === "history" ? loc.srcQuery : loc.srcHash;
|
|
884
|
+
if (path !== currentSrc) {
|
|
851
885
|
silent = silentFlag ? 1 : 0;
|
|
852
|
-
|
|
886
|
+
updateBrowserUrl(path, replace);
|
|
853
887
|
}
|
|
854
888
|
}
|
|
855
889
|
var Router = {
|
|
@@ -863,10 +897,29 @@ var Router = {
|
|
|
863
897
|
if (cached) {
|
|
864
898
|
return cached;
|
|
865
899
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
900
|
+
let srcQuery;
|
|
901
|
+
let srcHash;
|
|
902
|
+
let query;
|
|
903
|
+
let hash;
|
|
904
|
+
if (routeMode === "history") {
|
|
905
|
+
try {
|
|
906
|
+
const urlObj = new URL(href, window.location.origin);
|
|
907
|
+
srcQuery = urlObj.pathname + urlObj.search;
|
|
908
|
+
srcHash = urlObj.hash ? urlObj.hash.replace(/^#!?/, "") : "";
|
|
909
|
+
query = parseUri(srcQuery);
|
|
910
|
+
hash = srcHash ? parseUri(srcHash) : { path: "", params: {} };
|
|
911
|
+
} catch {
|
|
912
|
+
srcQuery = href.replace(URL_TRIM_HASH_REGEXP, "");
|
|
913
|
+
srcHash = href.replace(URL_TRIM_QUERY_REGEXP, "");
|
|
914
|
+
query = parseUri(srcQuery);
|
|
915
|
+
hash = parseUri(srcHash);
|
|
916
|
+
}
|
|
917
|
+
} else {
|
|
918
|
+
srcQuery = href.replace(URL_TRIM_HASH_REGEXP, "");
|
|
919
|
+
srcHash = href.replace(URL_TRIM_QUERY_REGEXP, "");
|
|
920
|
+
query = parseUri(srcQuery);
|
|
921
|
+
hash = parseUri(srcHash);
|
|
922
|
+
}
|
|
870
923
|
const params = assign({}, query["params"], hash["params"]);
|
|
871
924
|
const location = {
|
|
872
925
|
href,
|
|
@@ -900,7 +953,7 @@ var Router = {
|
|
|
900
953
|
document.title = defaultTitle || document.title;
|
|
901
954
|
}
|
|
902
955
|
emitter2.fire(
|
|
903
|
-
|
|
956
|
+
RouterEvents.CHANGED,
|
|
904
957
|
lastChanged
|
|
905
958
|
);
|
|
906
959
|
}
|
|
@@ -933,16 +986,16 @@ var Router = {
|
|
|
933
986
|
}
|
|
934
987
|
const lPath = lastLocation["path"] || "";
|
|
935
988
|
const lParams = lastLocation["params"];
|
|
936
|
-
const lQuery =
|
|
989
|
+
const lQuery = /* @__PURE__ */ new Set();
|
|
937
990
|
for (const k in lastLocation.query["params"]) {
|
|
938
|
-
if (
|
|
939
|
-
lQuery
|
|
991
|
+
if (hasOwnProperty(lastLocation.query["params"], k)) {
|
|
992
|
+
lQuery.add(k);
|
|
940
993
|
}
|
|
941
994
|
}
|
|
942
995
|
if (tPath) {
|
|
943
|
-
if (!
|
|
944
|
-
for (const qKey
|
|
945
|
-
if (
|
|
996
|
+
if (routeMode === "hash" && !hasOwnProperty(window, "history")) {
|
|
997
|
+
for (const qKey of lQuery) {
|
|
998
|
+
if (!hasOwnProperty(tParams, qKey)) {
|
|
946
999
|
tParams[qKey] = "";
|
|
947
1000
|
}
|
|
948
1001
|
}
|
|
@@ -951,14 +1004,17 @@ var Router = {
|
|
|
951
1004
|
tPath = lPath;
|
|
952
1005
|
tParams = assign({}, lParams, tParams);
|
|
953
1006
|
}
|
|
954
|
-
updateUrl(
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
)
|
|
1007
|
+
updateUrl(tPath, tParams, lastLocation, replace, silentFlag, lQuery);
|
|
1008
|
+
},
|
|
1009
|
+
/**
|
|
1010
|
+
* Register an async-friendly navigation guard. See `RouterInterface.beforeEach`.
|
|
1011
|
+
*/
|
|
1012
|
+
beforeEach(guard) {
|
|
1013
|
+
beforeEachGuards.push(guard);
|
|
1014
|
+
return () => {
|
|
1015
|
+
const idx = beforeEachGuards.indexOf(guard);
|
|
1016
|
+
if (idx !== -1) beforeEachGuards.splice(idx, 1);
|
|
1017
|
+
};
|
|
962
1018
|
},
|
|
963
1019
|
/**
|
|
964
1020
|
* Join multiple path segments into a single path.
|
|
@@ -989,32 +1045,41 @@ var Router = {
|
|
|
989
1045
|
return Router;
|
|
990
1046
|
},
|
|
991
1047
|
/**
|
|
992
|
-
* Internal: bind
|
|
1048
|
+
* Internal: bind routing events and beforeunload.
|
|
993
1049
|
* Called by Framework.boot().
|
|
1050
|
+
* In hash mode, listens to hashchange + popstate.
|
|
1051
|
+
* In history mode, listens to popstate only.
|
|
994
1052
|
*/
|
|
995
1053
|
_bind() {
|
|
996
1054
|
defaultTitle = document.title;
|
|
997
|
-
|
|
1055
|
+
const getLocationKey = () => {
|
|
1056
|
+
if (routeMode === "history") {
|
|
1057
|
+
return window.location.pathname + window.location.search;
|
|
1058
|
+
}
|
|
1059
|
+
return Router.parse().srcHash;
|
|
1060
|
+
};
|
|
1061
|
+
let lastKey = getLocationKey();
|
|
998
1062
|
let suspend;
|
|
999
1063
|
const watchChange = () => {
|
|
1000
1064
|
if (suspend) {
|
|
1001
1065
|
return;
|
|
1002
1066
|
}
|
|
1067
|
+
hrefCache.clear();
|
|
1003
1068
|
const loc = Router.parse();
|
|
1004
|
-
const
|
|
1005
|
-
if (
|
|
1069
|
+
const newKey = routeMode === "history" ? loc.srcQuery : loc.srcHash;
|
|
1070
|
+
if (newKey !== lastKey) {
|
|
1006
1071
|
const changeEvent = {
|
|
1007
1072
|
p: 0,
|
|
1008
1073
|
reject: () => {
|
|
1009
1074
|
changeEvent.p = 1;
|
|
1010
1075
|
suspend = "";
|
|
1011
|
-
|
|
1076
|
+
updateBrowserUrl(lastKey);
|
|
1012
1077
|
},
|
|
1013
1078
|
resolve: () => {
|
|
1014
1079
|
changeEvent.p = 1;
|
|
1015
|
-
|
|
1080
|
+
lastKey = newKey;
|
|
1016
1081
|
suspend = "";
|
|
1017
|
-
|
|
1082
|
+
updateBrowserUrl(newKey);
|
|
1018
1083
|
Router.diff();
|
|
1019
1084
|
},
|
|
1020
1085
|
prevent: () => {
|
|
@@ -1022,20 +1087,51 @@ var Router = {
|
|
|
1022
1087
|
}
|
|
1023
1088
|
};
|
|
1024
1089
|
Router.fire(
|
|
1025
|
-
|
|
1090
|
+
RouterEvents.CHANGE,
|
|
1026
1091
|
changeEvent
|
|
1027
1092
|
);
|
|
1028
|
-
if (
|
|
1093
|
+
if (suspend || changeEvent.p) {
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
if (beforeEachGuards.length === 0) {
|
|
1029
1097
|
changeEvent.resolve();
|
|
1098
|
+
return;
|
|
1099
|
+
}
|
|
1100
|
+
const from = lastLocation;
|
|
1101
|
+
const to = loc;
|
|
1102
|
+
const guards = beforeEachGuards.slice();
|
|
1103
|
+
let chain = Promise.resolve(true);
|
|
1104
|
+
for (const guard of guards) {
|
|
1105
|
+
chain = chain.then((prev) => {
|
|
1106
|
+
if (prev === false) return false;
|
|
1107
|
+
return guard(to, from);
|
|
1108
|
+
});
|
|
1030
1109
|
}
|
|
1110
|
+
chain.then(
|
|
1111
|
+
(result) => {
|
|
1112
|
+
if (changeEvent.p) return;
|
|
1113
|
+
if (result === false) {
|
|
1114
|
+
changeEvent.reject();
|
|
1115
|
+
} else {
|
|
1116
|
+
changeEvent.resolve();
|
|
1117
|
+
}
|
|
1118
|
+
},
|
|
1119
|
+
() => {
|
|
1120
|
+
if (!changeEvent.p) changeEvent.reject();
|
|
1121
|
+
}
|
|
1122
|
+
);
|
|
1031
1123
|
}
|
|
1032
1124
|
};
|
|
1033
1125
|
Router.notify = watchChange;
|
|
1034
|
-
|
|
1035
|
-
|
|
1126
|
+
if (routeMode === "history") {
|
|
1127
|
+
window.addEventListener("popstate", watchChange);
|
|
1128
|
+
} else {
|
|
1129
|
+
window.addEventListener("hashchange", watchChange);
|
|
1130
|
+
window.addEventListener("popstate", watchChange);
|
|
1131
|
+
}
|
|
1036
1132
|
window.addEventListener("beforeunload", (domEvent) => {
|
|
1037
1133
|
const data = {};
|
|
1038
|
-
Router.fire(
|
|
1134
|
+
Router.fire(RouterEvents.PAGE_UNLOAD, data);
|
|
1039
1135
|
const msg = data["msg"];
|
|
1040
1136
|
if (msg) {
|
|
1041
1137
|
domEvent.returnValue = msg;
|
|
@@ -1048,11 +1144,15 @@ var Router = {
|
|
|
1048
1144
|
*/
|
|
1049
1145
|
_setConfig(cfg) {
|
|
1050
1146
|
frameworkConfig = cfg;
|
|
1147
|
+
routeMode = cfg.routeMode || "history";
|
|
1051
1148
|
}
|
|
1052
1149
|
};
|
|
1053
1150
|
function markRouterBooted() {
|
|
1054
1151
|
booted2 = true;
|
|
1055
1152
|
}
|
|
1153
|
+
function getRouteMode() {
|
|
1154
|
+
return routeMode;
|
|
1155
|
+
}
|
|
1056
1156
|
|
|
1057
1157
|
// src/event-delegator.ts
|
|
1058
1158
|
var rootEvents = {};
|
|
@@ -1081,13 +1181,17 @@ function parseEventInfo(eventInfo) {
|
|
|
1081
1181
|
}
|
|
1082
1182
|
function findFrameInfo(current, eventType) {
|
|
1083
1183
|
const eventInfos = [];
|
|
1084
|
-
let begin = current;
|
|
1085
1184
|
const info = current.getAttribute(`@${eventType}`);
|
|
1185
|
+
const hasSelectorEvents = !!selectorEvents[eventType];
|
|
1186
|
+
if (!info && !hasSelectorEvents) {
|
|
1187
|
+
return eventInfos;
|
|
1188
|
+
}
|
|
1189
|
+
let begin = current;
|
|
1086
1190
|
let match;
|
|
1087
1191
|
if (info) {
|
|
1088
1192
|
match = parseEventInfo(info);
|
|
1089
1193
|
}
|
|
1090
|
-
if (match && !match.id ||
|
|
1194
|
+
if (match && !match.id || hasSelectorEvents) {
|
|
1091
1195
|
let selectorFrameId = "#";
|
|
1092
1196
|
let backtrace = 0;
|
|
1093
1197
|
while (begin && begin !== document.body) {
|
|
@@ -1260,7 +1364,7 @@ var EventDelegator = {
|
|
|
1260
1364
|
};
|
|
1261
1365
|
|
|
1262
1366
|
// src/vdom.ts
|
|
1263
|
-
var
|
|
1367
|
+
var wrapMeta = {
|
|
1264
1368
|
option: [1, "<select multiple>"],
|
|
1265
1369
|
thead: [1, "<table>"],
|
|
1266
1370
|
col: [2, "<table><colgroup>"],
|
|
@@ -1272,9 +1376,9 @@ var WrapMeta = {
|
|
|
1272
1376
|
math: [1, '<math xmlns="' + MATH_NS + '">'],
|
|
1273
1377
|
_: [0, ""]
|
|
1274
1378
|
};
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1379
|
+
wrapMeta["optgroup"] = wrapMeta["option"];
|
|
1380
|
+
wrapMeta["tbody"] = wrapMeta["tfoot"] = wrapMeta["colgroup"] = wrapMeta["caption"] = wrapMeta["thead"];
|
|
1381
|
+
wrapMeta["th"] = wrapMeta["td"];
|
|
1278
1382
|
var VDoc = document.implementation.createHTMLDocument("");
|
|
1279
1383
|
var VBase = VDoc.createElement("base");
|
|
1280
1384
|
VBase.href = document.location.href;
|
|
@@ -1285,16 +1389,12 @@ var VDomSpecials = {
|
|
|
1285
1389
|
OPTION: ["selected"]
|
|
1286
1390
|
};
|
|
1287
1391
|
function vdomUnmountFrames(frame, node) {
|
|
1288
|
-
if (node
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
if (children.includes(id)) {
|
|
1295
|
-
frame.unmountFrame(id);
|
|
1296
|
-
}
|
|
1297
|
-
}
|
|
1392
|
+
if (!(node instanceof Element)) return;
|
|
1393
|
+
const id = node.getAttribute("id");
|
|
1394
|
+
if (!id) return;
|
|
1395
|
+
frame.unmountZone(id);
|
|
1396
|
+
if (frame.children().includes(id)) {
|
|
1397
|
+
frame.unmountFrame(id);
|
|
1298
1398
|
}
|
|
1299
1399
|
}
|
|
1300
1400
|
function vdomGetNode(html, refNode) {
|
|
@@ -1309,7 +1409,7 @@ function vdomGetNode(html, refNode) {
|
|
|
1309
1409
|
const match = TAG_NAME_REGEXP.exec(html);
|
|
1310
1410
|
tag = match ? match[1] : "";
|
|
1311
1411
|
}
|
|
1312
|
-
const wrap =
|
|
1412
|
+
const wrap = wrapMeta[tag] || wrapMeta["_"];
|
|
1313
1413
|
tmp.innerHTML = wrap[1] + html;
|
|
1314
1414
|
let j = wrap[0];
|
|
1315
1415
|
while (j--) {
|
|
@@ -1326,7 +1426,7 @@ function vdomGetCompareKey(node) {
|
|
|
1326
1426
|
}
|
|
1327
1427
|
let key = el.autoId ? "" : el.getAttribute("id") || void 0;
|
|
1328
1428
|
if (!key) {
|
|
1329
|
-
key = el.getAttribute(
|
|
1429
|
+
key = el.getAttribute(LarkInnerKeys.DIFF_KEY) || void 0;
|
|
1330
1430
|
}
|
|
1331
1431
|
if (!key) {
|
|
1332
1432
|
const larkView = el.getAttribute(LARK_VIEW);
|
|
@@ -1339,8 +1439,7 @@ function vdomGetCompareKey(node) {
|
|
|
1339
1439
|
return key;
|
|
1340
1440
|
}
|
|
1341
1441
|
function vdomSpecialDiff(oldNode, newNode) {
|
|
1342
|
-
const
|
|
1343
|
-
const specials = VDomSpecials[nodeName];
|
|
1442
|
+
const specials = VDomSpecials[oldNode.nodeName];
|
|
1344
1443
|
if (!specials) return 0;
|
|
1345
1444
|
const oldEl = oldNode;
|
|
1346
1445
|
const newEl = newNode;
|
|
@@ -1389,13 +1488,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1389
1488
|
let oldNode = oldParent.lastChild;
|
|
1390
1489
|
let newNode = newParent.firstChild;
|
|
1391
1490
|
let extra = 0;
|
|
1392
|
-
const keyedNodes =
|
|
1393
|
-
const newKeyedNodes =
|
|
1491
|
+
const keyedNodes = /* @__PURE__ */ new Map();
|
|
1492
|
+
const newKeyedNodes = /* @__PURE__ */ new Map();
|
|
1394
1493
|
while (oldNode) {
|
|
1395
1494
|
extra++;
|
|
1396
1495
|
const nodeKey = vdomGetCompareKey(oldNode);
|
|
1397
1496
|
if (nodeKey) {
|
|
1398
|
-
|
|
1497
|
+
let bucket = keyedNodes.get(nodeKey);
|
|
1498
|
+
if (!bucket) {
|
|
1499
|
+
bucket = [];
|
|
1500
|
+
keyedNodes.set(nodeKey, bucket);
|
|
1501
|
+
}
|
|
1399
1502
|
bucket.push(oldNode);
|
|
1400
1503
|
}
|
|
1401
1504
|
oldNode = oldNode.previousSibling;
|
|
@@ -1403,7 +1506,7 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1403
1506
|
while (newNode) {
|
|
1404
1507
|
const nodeKey = vdomGetCompareKey(newNode);
|
|
1405
1508
|
if (nodeKey) {
|
|
1406
|
-
newKeyedNodes
|
|
1509
|
+
newKeyedNodes.set(nodeKey, (newKeyedNodes.get(nodeKey) ?? 0) + 1);
|
|
1407
1510
|
}
|
|
1408
1511
|
newNode = newNode.nextSibling;
|
|
1409
1512
|
}
|
|
@@ -1414,23 +1517,25 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1414
1517
|
const tempNew = newNode;
|
|
1415
1518
|
newNode = newNode.nextSibling;
|
|
1416
1519
|
const nodeKey = vdomGetCompareKey(tempNew);
|
|
1417
|
-
let foundNode = nodeKey ? keyedNodes
|
|
1520
|
+
let foundNode = nodeKey ? keyedNodes.get(nodeKey) : void 0;
|
|
1418
1521
|
if (foundNode && (foundNode = foundNode.slice()) && foundNode.length) {
|
|
1419
1522
|
const matched = foundNode.pop();
|
|
1420
1523
|
while (matched !== oldNode) {
|
|
1421
|
-
|
|
1524
|
+
if (!oldNode) break;
|
|
1525
|
+
const next = oldNode.nextSibling;
|
|
1422
1526
|
oldParent.appendChild(oldNode);
|
|
1423
1527
|
oldNode = next;
|
|
1424
1528
|
}
|
|
1425
1529
|
oldNode = matched.nextSibling;
|
|
1426
|
-
if (nodeKey
|
|
1427
|
-
newKeyedNodes
|
|
1530
|
+
if (nodeKey) {
|
|
1531
|
+
const c = newKeyedNodes.get(nodeKey);
|
|
1532
|
+
if (c) newKeyedNodes.set(nodeKey, c - 1);
|
|
1428
1533
|
}
|
|
1429
1534
|
vdomSetNode(matched, tempNew, oldParent, ref, frame, keys_);
|
|
1430
1535
|
} else if (oldNode) {
|
|
1431
1536
|
const tempOld2 = oldNode;
|
|
1432
1537
|
const oldKey = vdomGetCompareKey(tempOld2);
|
|
1433
|
-
if (oldKey && keyedNodes
|
|
1538
|
+
if (oldKey && keyedNodes.has(oldKey) && newKeyedNodes.get(oldKey)) {
|
|
1434
1539
|
extra++;
|
|
1435
1540
|
ref.hasChanged = 1;
|
|
1436
1541
|
ref.domOps.push([8, oldParent, tempNew, tempOld2]);
|
|
@@ -1454,17 +1559,21 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
|
|
|
1454
1559
|
}
|
|
1455
1560
|
}
|
|
1456
1561
|
function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
|
|
1457
|
-
|
|
1562
|
+
const oldAsEl = oldNode instanceof Element ? oldNode : null;
|
|
1563
|
+
const newAsEl = newNode instanceof Element ? newNode : null;
|
|
1564
|
+
const hasViewKey = !!oldAsEl?.hasAttribute(LarkInnerKeys.VIEW_KEY);
|
|
1565
|
+
const equalAsNodes = oldAsEl !== null && newAsEl !== null && oldAsEl.isEqualNode && oldAsEl.isEqualNode(newAsEl);
|
|
1566
|
+
if (vdomSpecialDiff(oldNode, newNode) || hasViewKey || !equalAsNodes) {
|
|
1458
1567
|
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(
|
|
1568
|
+
if (oldAsEl !== null && newAsEl !== null) {
|
|
1569
|
+
const oldEl = oldAsEl;
|
|
1570
|
+
const newEl = newAsEl;
|
|
1571
|
+
const staticKey = newEl.getAttribute(LarkInnerKeys.DIFF_KEY);
|
|
1572
|
+
if (staticKey && staticKey === oldEl.getAttribute(LarkInnerKeys.DIFF_KEY)) {
|
|
1464
1573
|
return;
|
|
1465
1574
|
}
|
|
1466
1575
|
const newLarkView = newEl.getAttribute(LARK_VIEW);
|
|
1467
|
-
const updateAttribute = !newEl.getAttribute(
|
|
1576
|
+
const updateAttribute = !newEl.getAttribute(LarkInnerKeys.ATTR_KEY) || newEl.getAttribute(LarkInnerKeys.ATTR_KEY) !== oldEl.getAttribute(LarkInnerKeys.ATTR_KEY);
|
|
1468
1577
|
let updateChildren = true;
|
|
1469
1578
|
if (newLarkView) {
|
|
1470
1579
|
const oldFrameId = oldEl.getAttribute("id") || "";
|
|
@@ -1565,7 +1674,8 @@ function encodeQ(v) {
|
|
|
1565
1674
|
}
|
|
1566
1675
|
|
|
1567
1676
|
// src/updater.ts
|
|
1568
|
-
function updaterRef(
|
|
1677
|
+
function updaterRef(refDataIn, value, key) {
|
|
1678
|
+
const refData = refDataIn;
|
|
1569
1679
|
const counter = refData[SPLITTER];
|
|
1570
1680
|
for (let i = counter; --i; ) {
|
|
1571
1681
|
key = SPLITTER + i;
|
|
@@ -1585,13 +1695,19 @@ var Updater = class {
|
|
|
1585
1695
|
/** Ref data for template rendering */
|
|
1586
1696
|
refData;
|
|
1587
1697
|
/** Changed keys in current digest cycle */
|
|
1588
|
-
changedKeys =
|
|
1698
|
+
changedKeys = /* @__PURE__ */ new Set();
|
|
1589
1699
|
/** Whether data has changed since last digest */
|
|
1590
1700
|
hasChangedFlag = 0;
|
|
1591
|
-
/**
|
|
1701
|
+
/**
|
|
1702
|
+
* Digesting queue: supports re-digest during digest.
|
|
1703
|
+
* Holds pending callbacks; `null` is used as a sentinel marking the start
|
|
1704
|
+
* of an active digest cycle, so `runDigest` can detect re-entrant calls.
|
|
1705
|
+
*/
|
|
1592
1706
|
digestingQueue = [];
|
|
1593
|
-
/**
|
|
1594
|
-
|
|
1707
|
+
/** Monotonically increasing version, bumped each time data actually changes. */
|
|
1708
|
+
version = 0;
|
|
1709
|
+
/** Snapshot of `version` taken by `snapshot()`, used by `altered()`. */
|
|
1710
|
+
snapshotVersion;
|
|
1595
1711
|
constructor(viewId) {
|
|
1596
1712
|
this.viewId = viewId;
|
|
1597
1713
|
this.data = { vId: viewId };
|
|
@@ -1619,7 +1735,16 @@ var Updater = class {
|
|
|
1619
1735
|
* Returns this for chaining.
|
|
1620
1736
|
*/
|
|
1621
1737
|
set(data, excludes) {
|
|
1622
|
-
|
|
1738
|
+
const changed = setData(
|
|
1739
|
+
data,
|
|
1740
|
+
this.data,
|
|
1741
|
+
this.changedKeys,
|
|
1742
|
+
excludes || EMPTY_STRING_SET
|
|
1743
|
+
);
|
|
1744
|
+
if (changed) {
|
|
1745
|
+
this.version++;
|
|
1746
|
+
this.hasChangedFlag = 1;
|
|
1747
|
+
}
|
|
1623
1748
|
return this;
|
|
1624
1749
|
}
|
|
1625
1750
|
/**
|
|
@@ -1655,13 +1780,13 @@ var Updater = class {
|
|
|
1655
1780
|
const keys2 = this.changedKeys;
|
|
1656
1781
|
const changed = this.hasChangedFlag;
|
|
1657
1782
|
this.hasChangedFlag = 0;
|
|
1658
|
-
this.changedKeys =
|
|
1783
|
+
this.changedKeys = /* @__PURE__ */ new Set();
|
|
1659
1784
|
const frame = Frame.get(this.viewId);
|
|
1660
1785
|
const view = frame?.view;
|
|
1661
1786
|
const node = getById(this.viewId);
|
|
1662
|
-
if (changed && view && node && view.signature > 0) {
|
|
1787
|
+
if (changed && view && node && view.signature > 0 && frame) {
|
|
1663
1788
|
const template = view.template;
|
|
1664
|
-
if (
|
|
1789
|
+
if (typeof template === "function") {
|
|
1665
1790
|
const html = template(
|
|
1666
1791
|
this.data,
|
|
1667
1792
|
this.viewId,
|
|
@@ -1698,43 +1823,65 @@ var Updater = class {
|
|
|
1698
1823
|
}
|
|
1699
1824
|
}
|
|
1700
1825
|
/**
|
|
1701
|
-
* Save a snapshot of current data for altered() detection.
|
|
1826
|
+
* Save a snapshot of the current data version for `altered()` detection.
|
|
1827
|
+
* Cheap O(1) — records the current monotonic version, no serialization.
|
|
1702
1828
|
*/
|
|
1703
1829
|
snapshot() {
|
|
1704
|
-
this.
|
|
1830
|
+
this.snapshotVersion = this.version;
|
|
1705
1831
|
return this;
|
|
1706
1832
|
}
|
|
1707
1833
|
/**
|
|
1708
|
-
* Check
|
|
1834
|
+
* Check whether data has changed since the last snapshot.
|
|
1835
|
+
* Returns undefined when no snapshot has been taken yet.
|
|
1709
1836
|
*/
|
|
1710
1837
|
altered() {
|
|
1711
|
-
if (this.
|
|
1712
|
-
|
|
1713
|
-
}
|
|
1714
|
-
return void 0;
|
|
1838
|
+
if (this.snapshotVersion === void 0) return void 0;
|
|
1839
|
+
return this.version !== this.snapshotVersion;
|
|
1715
1840
|
}
|
|
1716
1841
|
/**
|
|
1717
|
-
* Translate
|
|
1842
|
+
* Translate a refData reference back to its original value.
|
|
1843
|
+
*
|
|
1844
|
+
* The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
|
|
1845
|
+
* emitted by `updaterRef`. We require that exact shape so a user-supplied
|
|
1846
|
+
* string that merely begins with SPLITTER is never accidentally resolved
|
|
1847
|
+
* (or mishandled as a "missing ref").
|
|
1718
1848
|
*/
|
|
1719
1849
|
translate(data) {
|
|
1720
|
-
if (typeof data
|
|
1721
|
-
|
|
1850
|
+
if (typeof data !== "string") return data;
|
|
1851
|
+
if (data.length < 2 || data[0] !== SPLITTER) return data;
|
|
1852
|
+
for (let i = 1; i < data.length; i++) {
|
|
1853
|
+
const c = data.charCodeAt(i);
|
|
1854
|
+
if (c < 48 || c > 57) return data;
|
|
1722
1855
|
}
|
|
1723
|
-
return data;
|
|
1856
|
+
return hasOwnProperty(this.refData, data) ? this.refData[data] : data;
|
|
1724
1857
|
}
|
|
1725
1858
|
/**
|
|
1726
|
-
*
|
|
1859
|
+
* Resolve a dotted property path against refData.
|
|
1860
|
+
*
|
|
1861
|
+
* Only safe property-path syntax is supported: `a`, `a.b`, `a.b.c`.
|
|
1862
|
+
* Numeric literals (e.g. `1`, `1.5`) are returned as numbers. Anything else
|
|
1863
|
+
* returns `undefined` — we no longer evaluate arbitrary JavaScript via
|
|
1864
|
+
* `new Function`, so the method is CSP-safe and cannot be used as an
|
|
1865
|
+
* injection vector.
|
|
1727
1866
|
*/
|
|
1728
1867
|
parse(expr) {
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1868
|
+
const trimmed = expr.trim();
|
|
1869
|
+
if (!trimmed) return void 0;
|
|
1870
|
+
if (/^-?\d+(?:\.\d+)?$/.test(trimmed)) {
|
|
1871
|
+
return Number(trimmed);
|
|
1872
|
+
}
|
|
1873
|
+
if (!/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(trimmed)) {
|
|
1733
1874
|
return void 0;
|
|
1734
1875
|
}
|
|
1876
|
+
let cur = this.refData;
|
|
1877
|
+
for (const segment of trimmed.split(".")) {
|
|
1878
|
+
if (cur == null || typeof cur !== "object") return void 0;
|
|
1879
|
+
cur = cur[segment];
|
|
1880
|
+
}
|
|
1881
|
+
return cur;
|
|
1735
1882
|
}
|
|
1736
1883
|
/**
|
|
1737
|
-
* Get
|
|
1884
|
+
* Get the set of keys changed since the last digest (for external inspection).
|
|
1738
1885
|
*/
|
|
1739
1886
|
getChangedKeys() {
|
|
1740
1887
|
return this.changedKeys;
|
|
@@ -1781,30 +1928,31 @@ var View = class _View {
|
|
|
1781
1928
|
// ============================================================
|
|
1782
1929
|
// Getters for prototype-stored event maps
|
|
1783
1930
|
// ============================================================
|
|
1931
|
+
/** Prototype-stored event maps shape (set by View.prepare). */
|
|
1932
|
+
get protoEventState() {
|
|
1933
|
+
return Object.getPrototypeOf(this);
|
|
1934
|
+
}
|
|
1784
1935
|
/**
|
|
1785
1936
|
* Event bitmask map: eventType -> bitmask (1=root, 2=selector).
|
|
1786
1937
|
* Read from prototype ($evtObjMap) set by View.prepare.
|
|
1787
1938
|
* Using a getter avoids ES6 class field shadowing the prototype value.
|
|
1788
1939
|
*/
|
|
1789
1940
|
get eventObjectMap() {
|
|
1790
|
-
|
|
1791
|
-
return proto["$evtObjMap"] || {};
|
|
1941
|
+
return this.protoEventState.$evtObjMap ?? {};
|
|
1792
1942
|
}
|
|
1793
1943
|
/**
|
|
1794
1944
|
* Selector event map: eventType -> selector list.
|
|
1795
1945
|
* Read from prototype ($selMap) set by View.prepare.
|
|
1796
1946
|
*/
|
|
1797
1947
|
get eventSelectorMap() {
|
|
1798
|
-
|
|
1799
|
-
return proto["$selMap"] || {};
|
|
1948
|
+
return this.protoEventState.$selMap ?? {};
|
|
1800
1949
|
}
|
|
1801
1950
|
/**
|
|
1802
1951
|
* Global event list: [{handler, element, eventName, modifiers}].
|
|
1803
1952
|
* Read from prototype ($globalEvtList) set by View.prepare.
|
|
1804
1953
|
*/
|
|
1805
1954
|
get globalEventList() {
|
|
1806
|
-
|
|
1807
|
-
return proto["$globalEvtList"] || [];
|
|
1955
|
+
return this.protoEventState.$globalEvtList ?? [];
|
|
1808
1956
|
}
|
|
1809
1957
|
// ============================================================
|
|
1810
1958
|
// Instance lifecycle methods
|
|
@@ -1839,13 +1987,17 @@ var View = class _View {
|
|
|
1839
1987
|
// ============================================================
|
|
1840
1988
|
// Update methods
|
|
1841
1989
|
// ============================================================
|
|
1990
|
+
/** Get the owning frame, asserting it has been bound. */
|
|
1991
|
+
get ownerFrame() {
|
|
1992
|
+
return this.owner;
|
|
1993
|
+
}
|
|
1842
1994
|
/**
|
|
1843
1995
|
* Notify view that HTML update is about to begin.
|
|
1844
1996
|
* Unmounts child frames in the update zone.
|
|
1845
1997
|
*/
|
|
1846
1998
|
beginUpdate(id) {
|
|
1847
1999
|
if (this.signature > 0 && this.endUpdatePending !== void 0) {
|
|
1848
|
-
this.
|
|
2000
|
+
this.ownerFrame.unmountZone(id, true);
|
|
1849
2001
|
}
|
|
1850
2002
|
}
|
|
1851
2003
|
/**
|
|
@@ -1863,7 +2015,7 @@ var View = class _View {
|
|
|
1863
2015
|
this.endUpdatePending = 1;
|
|
1864
2016
|
this.rendered = true;
|
|
1865
2017
|
}
|
|
1866
|
-
const ownerFrame = this.
|
|
2018
|
+
const ownerFrame = this.ownerFrame;
|
|
1867
2019
|
ownerFrame.mountZone(updateId, inner);
|
|
1868
2020
|
if (!flag) {
|
|
1869
2021
|
setTimeout(
|
|
@@ -1902,11 +2054,12 @@ var View = class _View {
|
|
|
1902
2054
|
const loc = this.locationObserved;
|
|
1903
2055
|
loc.flag = 1;
|
|
1904
2056
|
if (typeof params === "object" && !Array.isArray(params)) {
|
|
1905
|
-
|
|
2057
|
+
const opts = params;
|
|
2058
|
+
if (opts["path"]) {
|
|
1906
2059
|
observePath = true;
|
|
1907
2060
|
}
|
|
1908
|
-
const paramKeys =
|
|
1909
|
-
if (paramKeys) {
|
|
2061
|
+
const paramKeys = opts["params"];
|
|
2062
|
+
if (typeof paramKeys === "string" || Array.isArray(paramKeys)) {
|
|
1910
2063
|
params = paramKeys;
|
|
1911
2064
|
}
|
|
1912
2065
|
}
|
|
@@ -1970,24 +2123,16 @@ var View = class _View {
|
|
|
1970
2123
|
*/
|
|
1971
2124
|
leaveTip(message, condition) {
|
|
1972
2125
|
const changeListener = function(e) {
|
|
1973
|
-
const isRouterChange = e.type ===
|
|
2126
|
+
const isRouterChange = e.type === RouterEvents.CHANGE;
|
|
1974
2127
|
const aKey = isRouterChange ? "a" : "b";
|
|
1975
2128
|
const bKey = isRouterChange ? "b" : "a";
|
|
1976
2129
|
if (changeListener[aKey]) {
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
}
|
|
1980
|
-
if (typeof e.reject === "function") {
|
|
1981
|
-
e.reject();
|
|
1982
|
-
}
|
|
2130
|
+
e.prevent?.();
|
|
2131
|
+
e.reject?.();
|
|
1983
2132
|
} else if (condition()) {
|
|
1984
|
-
|
|
1985
|
-
e.prevent();
|
|
1986
|
-
}
|
|
2133
|
+
e.prevent?.();
|
|
1987
2134
|
changeListener[bKey] = 1;
|
|
1988
|
-
|
|
1989
|
-
e.resolve();
|
|
1990
|
-
}
|
|
2135
|
+
e.resolve?.();
|
|
1991
2136
|
}
|
|
1992
2137
|
};
|
|
1993
2138
|
const unloadListener = (e) => {
|
|
@@ -1995,14 +2140,12 @@ var View = class _View {
|
|
|
1995
2140
|
e["msg"] = message;
|
|
1996
2141
|
}
|
|
1997
2142
|
};
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
Router.on(ROUTER_EVENTS.PAGE_UNLOAD, unloadFn);
|
|
2002
|
-
this.on("unload", changeFn);
|
|
2143
|
+
Router.on(RouterEvents.CHANGE, changeListener);
|
|
2144
|
+
Router.on(RouterEvents.PAGE_UNLOAD, unloadListener);
|
|
2145
|
+
this.on("unload", changeListener);
|
|
2003
2146
|
this.on("destroy", () => {
|
|
2004
|
-
Router.off(
|
|
2005
|
-
Router.off(
|
|
2147
|
+
Router.off(RouterEvents.CHANGE, changeListener);
|
|
2148
|
+
Router.off(RouterEvents.PAGE_UNLOAD, unloadListener);
|
|
2006
2149
|
});
|
|
2007
2150
|
}
|
|
2008
2151
|
// ============================================================
|
|
@@ -2032,7 +2175,7 @@ var View = class _View {
|
|
|
2032
2175
|
_View.mergeMixins(mixins, oView, ctors);
|
|
2033
2176
|
}
|
|
2034
2177
|
for (const p in proto) {
|
|
2035
|
-
if (!
|
|
2178
|
+
if (!hasOwnProperty(proto, p)) continue;
|
|
2036
2179
|
const currentFn = proto[p];
|
|
2037
2180
|
if (typeof currentFn !== "function") continue;
|
|
2038
2181
|
const matches = p.match(VIEW_EVENT_METHOD_REGEXP);
|
|
@@ -2078,16 +2221,16 @@ var View = class _View {
|
|
|
2078
2221
|
const existingFn = proto[combinedKey];
|
|
2079
2222
|
if (!existingFn) {
|
|
2080
2223
|
proto[combinedKey] = currentFn;
|
|
2081
|
-
} else {
|
|
2224
|
+
} else if (typeof existingFn === "function") {
|
|
2082
2225
|
const mixinFn = currentFn;
|
|
2083
2226
|
const existingMixin = existingFn;
|
|
2084
2227
|
if (existingMixin.marker) {
|
|
2085
2228
|
if (mixinFn.marker) {
|
|
2086
2229
|
proto[combinedKey] = _View.processMixinsSameEvent(
|
|
2087
|
-
|
|
2088
|
-
|
|
2230
|
+
mixinFn,
|
|
2231
|
+
existingMixin
|
|
2089
2232
|
);
|
|
2090
|
-
} else if (
|
|
2233
|
+
} else if (hasOwnProperty(proto, p)) {
|
|
2091
2234
|
proto[combinedKey] = currentFn;
|
|
2092
2235
|
}
|
|
2093
2236
|
}
|
|
@@ -2110,7 +2253,7 @@ var View = class _View {
|
|
|
2110
2253
|
const selectorObject = view.eventSelectorMap;
|
|
2111
2254
|
const eventsList = view.globalEventList;
|
|
2112
2255
|
for (const e in eventsObject) {
|
|
2113
|
-
if (
|
|
2256
|
+
if (hasOwnProperty(eventsObject, e)) {
|
|
2114
2257
|
if (destroy) {
|
|
2115
2258
|
EventDelegator.unbind(e, !!selectorObject[e]);
|
|
2116
2259
|
} else {
|
|
@@ -2153,7 +2296,7 @@ var View = class _View {
|
|
|
2153
2296
|
static destroyAllResources(view, lastly) {
|
|
2154
2297
|
const cache = view.resources;
|
|
2155
2298
|
for (const p in cache) {
|
|
2156
|
-
if (
|
|
2299
|
+
if (hasOwnProperty(cache, p)) {
|
|
2157
2300
|
const entry = cache[p];
|
|
2158
2301
|
if (lastly || entry.destroyOnRender) {
|
|
2159
2302
|
_View.destroyResource(cache, p, true);
|
|
@@ -2183,13 +2326,16 @@ var View = class _View {
|
|
|
2183
2326
|
static wrapMethod(proto, fnName, shortKey) {
|
|
2184
2327
|
const originalFn = proto[fnName];
|
|
2185
2328
|
if (typeof originalFn !== "function") return;
|
|
2329
|
+
const originalAsFn = originalFn;
|
|
2186
2330
|
const wrapped = function(...args) {
|
|
2187
2331
|
if (this.signature > 0) {
|
|
2188
2332
|
this.signature++;
|
|
2189
2333
|
this.fire("render");
|
|
2190
2334
|
_View.destroyAllResources(this, false);
|
|
2191
|
-
const
|
|
2192
|
-
const
|
|
2335
|
+
const lookup = this;
|
|
2336
|
+
const candidate = lookup[fnName];
|
|
2337
|
+
const instanceFn = typeof candidate === "function" ? candidate : originalAsFn;
|
|
2338
|
+
const fnToCall = instanceFn === wrapped ? originalAsFn : instanceFn;
|
|
2193
2339
|
return funcWithTry(fnToCall, args, this, noop);
|
|
2194
2340
|
}
|
|
2195
2341
|
return void 0;
|
|
@@ -2203,19 +2349,18 @@ var View = class _View {
|
|
|
2203
2349
|
*/
|
|
2204
2350
|
static processMixinsSameEvent(additional, exist) {
|
|
2205
2351
|
let temp;
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
temp = existMixin;
|
|
2352
|
+
if (exist.handlerList) {
|
|
2353
|
+
temp = exist;
|
|
2209
2354
|
} else {
|
|
2210
|
-
|
|
2211
|
-
funcWithTry(
|
|
2355
|
+
const merged = function(...e) {
|
|
2356
|
+
funcWithTry(merged.handlerList ?? [], e, this, noop);
|
|
2212
2357
|
};
|
|
2213
|
-
|
|
2214
|
-
|
|
2358
|
+
merged.handlerList = [exist];
|
|
2359
|
+
merged.marker = 1;
|
|
2360
|
+
temp = merged;
|
|
2215
2361
|
}
|
|
2216
|
-
const additionalMixin = additional;
|
|
2217
2362
|
temp.handlerList = (temp.handlerList ?? []).concat(
|
|
2218
|
-
|
|
2363
|
+
additional.handlerList ?? [additional]
|
|
2219
2364
|
);
|
|
2220
2365
|
return temp;
|
|
2221
2366
|
}
|
|
@@ -2227,29 +2372,29 @@ var View = class _View {
|
|
|
2227
2372
|
const temp = {};
|
|
2228
2373
|
for (const node of mixins) {
|
|
2229
2374
|
for (const p in node) {
|
|
2230
|
-
if (!
|
|
2375
|
+
if (!hasOwnProperty(node, p)) continue;
|
|
2231
2376
|
const fn = node[p];
|
|
2377
|
+
if (typeof fn !== "function") continue;
|
|
2378
|
+
const mixinFn = fn;
|
|
2232
2379
|
const exist = temp[p];
|
|
2233
2380
|
if (p === "make") {
|
|
2234
|
-
ctors.push(
|
|
2381
|
+
ctors.push(mixinFn);
|
|
2235
2382
|
continue;
|
|
2236
2383
|
}
|
|
2237
2384
|
if (VIEW_EVENT_METHOD_REGEXP.test(p)) {
|
|
2238
2385
|
if (exist) {
|
|
2239
|
-
temp[p] = _View.processMixinsSameEvent(
|
|
2386
|
+
temp[p] = _View.processMixinsSameEvent(mixinFn, exist);
|
|
2240
2387
|
} else {
|
|
2241
|
-
|
|
2242
|
-
temp[p] =
|
|
2243
|
-
}
|
|
2244
|
-
} else {
|
|
2245
|
-
if (!exist) {
|
|
2246
|
-
temp[p] = fn;
|
|
2388
|
+
mixinFn.marker = 1;
|
|
2389
|
+
temp[p] = mixinFn;
|
|
2247
2390
|
}
|
|
2391
|
+
} else if (!exist) {
|
|
2392
|
+
temp[p] = mixinFn;
|
|
2248
2393
|
}
|
|
2249
2394
|
}
|
|
2250
2395
|
}
|
|
2251
2396
|
for (const p in temp) {
|
|
2252
|
-
if (!
|
|
2397
|
+
if (!hasOwnProperty(proto, p)) {
|
|
2253
2398
|
proto[p] = temp[p];
|
|
2254
2399
|
}
|
|
2255
2400
|
}
|
|
@@ -2282,19 +2427,20 @@ var View = class _View {
|
|
|
2282
2427
|
* - Event method patterns: `'name<click>'` etc.
|
|
2283
2428
|
*/
|
|
2284
2429
|
static extend(props, statics) {
|
|
2285
|
-
|
|
2286
|
-
const make =
|
|
2430
|
+
const definedProps = props ?? {};
|
|
2431
|
+
const make = definedProps["make"];
|
|
2287
2432
|
const ctors = [];
|
|
2288
|
-
if (make) {
|
|
2433
|
+
if (typeof make === "function") {
|
|
2289
2434
|
ctors.push(make);
|
|
2290
2435
|
}
|
|
2291
2436
|
const ParentView = this;
|
|
2292
2437
|
const ChildView = class extends ParentView {
|
|
2293
2438
|
constructor(nodeId, ownerFrame, initParams, node, mixinCtors) {
|
|
2294
2439
|
super(nodeId, ownerFrame, initParams, node, []);
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2440
|
+
const instanceProps = this;
|
|
2441
|
+
for (const key in definedProps) {
|
|
2442
|
+
if (hasOwnProperty(definedProps, key) && key !== "make" && key !== "render") {
|
|
2443
|
+
instanceProps[key] = definedProps[key];
|
|
2298
2444
|
}
|
|
2299
2445
|
}
|
|
2300
2446
|
this.id = nodeId;
|
|
@@ -2314,15 +2460,16 @@ var View = class _View {
|
|
|
2314
2460
|
}
|
|
2315
2461
|
};
|
|
2316
2462
|
const proto = ChildView.prototype;
|
|
2317
|
-
for (const key in
|
|
2318
|
-
if (
|
|
2319
|
-
proto[key] =
|
|
2463
|
+
for (const key in definedProps) {
|
|
2464
|
+
if (hasOwnProperty(definedProps, key) && key !== "make") {
|
|
2465
|
+
proto[key] = definedProps[key];
|
|
2320
2466
|
}
|
|
2321
2467
|
}
|
|
2322
2468
|
if (statics) {
|
|
2469
|
+
const staticTarget = ChildView;
|
|
2323
2470
|
for (const key in statics) {
|
|
2324
|
-
if (
|
|
2325
|
-
|
|
2471
|
+
if (hasOwnProperty(statics, key)) {
|
|
2472
|
+
staticTarget[key] = statics[key];
|
|
2326
2473
|
}
|
|
2327
2474
|
}
|
|
2328
2475
|
}
|
|
@@ -2337,14 +2484,87 @@ var View = class _View {
|
|
|
2337
2484
|
return this;
|
|
2338
2485
|
}
|
|
2339
2486
|
};
|
|
2487
|
+
function defineView(props, statics) {
|
|
2488
|
+
return View.extend(props, statics);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
// src/module-loader.ts
|
|
2492
|
+
var config = {
|
|
2493
|
+
rootId: "root",
|
|
2494
|
+
routeMode: "history",
|
|
2495
|
+
hashbang: "#!",
|
|
2496
|
+
error: (error) => {
|
|
2497
|
+
throw error;
|
|
2498
|
+
}
|
|
2499
|
+
};
|
|
2500
|
+
function use(names, callback) {
|
|
2501
|
+
const nameList = typeof names === "string" ? [names] : names;
|
|
2502
|
+
const loadPromise = (() => {
|
|
2503
|
+
if (config.require) {
|
|
2504
|
+
const result = config.require(nameList);
|
|
2505
|
+
if (result && typeof result.then === "function") {
|
|
2506
|
+
return result;
|
|
2507
|
+
}
|
|
2508
|
+
return Promise.resolve([]);
|
|
2509
|
+
}
|
|
2510
|
+
return Promise.all(
|
|
2511
|
+
nameList.map((name) => {
|
|
2512
|
+
const importPath = name.startsWith(".") || name.startsWith("/") ? name : `./${name}`;
|
|
2513
|
+
return import(
|
|
2514
|
+
/* @vite-ignore */
|
|
2515
|
+
/* webpackIgnore: true */
|
|
2516
|
+
importPath
|
|
2517
|
+
).then((mod) => {
|
|
2518
|
+
return mod && (mod["__esModule"] || // For Webpack
|
|
2519
|
+
typeof mod["default"] === "function") ? mod["default"] : mod;
|
|
2520
|
+
}).catch((err) => {
|
|
2521
|
+
const errorHandler = config.error;
|
|
2522
|
+
if (errorHandler) {
|
|
2523
|
+
errorHandler(err instanceof Error ? err : new Error(String(err)));
|
|
2524
|
+
}
|
|
2525
|
+
return void 0;
|
|
2526
|
+
});
|
|
2527
|
+
})
|
|
2528
|
+
);
|
|
2529
|
+
})();
|
|
2530
|
+
if (callback) {
|
|
2531
|
+
loadPromise.then((modules) => {
|
|
2532
|
+
callback(...modules);
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
return loadPromise;
|
|
2536
|
+
}
|
|
2537
|
+
|
|
2538
|
+
// src/view-registry.ts
|
|
2539
|
+
var viewClassRegistry = {};
|
|
2540
|
+
function getViewClass(path) {
|
|
2541
|
+
return viewClassRegistry[path];
|
|
2542
|
+
}
|
|
2543
|
+
function registerViewClass(viewPath, ViewClass) {
|
|
2544
|
+
const parsed = parseUri(viewPath);
|
|
2545
|
+
const path = parsed.path;
|
|
2546
|
+
if (path) {
|
|
2547
|
+
viewClassRegistry[path] = ViewClass;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
function invalidateViewClass(viewPath) {
|
|
2551
|
+
const parsed = parseUri(viewPath);
|
|
2552
|
+
const path = parsed.path;
|
|
2553
|
+
if (path) {
|
|
2554
|
+
Reflect.deleteProperty(viewClassRegistry, path);
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2557
|
+
function getViewClassRegistry() {
|
|
2558
|
+
return viewClassRegistry;
|
|
2559
|
+
}
|
|
2340
2560
|
|
|
2341
2561
|
// src/frame.ts
|
|
2342
2562
|
var frameRegistry = /* @__PURE__ */ new Map();
|
|
2343
2563
|
var rootFrame;
|
|
2344
2564
|
var globalAlter;
|
|
2565
|
+
var MAX_FRAME_POOL = 64;
|
|
2345
2566
|
var frameCache = [];
|
|
2346
2567
|
var staticEmitter = new EventEmitter();
|
|
2347
|
-
var viewClassRegistry = {};
|
|
2348
2568
|
var Frame = class _Frame extends EventEmitter {
|
|
2349
2569
|
/** Frame ID (same as owner DOM element ID) */
|
|
2350
2570
|
id;
|
|
@@ -2359,8 +2579,8 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2359
2579
|
childrenCount = 0;
|
|
2360
2580
|
/** Ready count (children that have fired 'created') */
|
|
2361
2581
|
readyCount = 0;
|
|
2362
|
-
/**
|
|
2363
|
-
readyMap =
|
|
2582
|
+
/** Set of child frame IDs that have fired 'created' */
|
|
2583
|
+
readyMap = /* @__PURE__ */ new Set();
|
|
2364
2584
|
/** View instance */
|
|
2365
2585
|
viewInstance;
|
|
2366
2586
|
/** Get view instance (read-only) */
|
|
@@ -2431,13 +2651,30 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2431
2651
|
this.viewPath = viewPath;
|
|
2432
2652
|
const params = parsed["params"];
|
|
2433
2653
|
translateQuery(pId || this.id, viewPath, params);
|
|
2654
|
+
const initParams = { ...params };
|
|
2434
2655
|
if (viewInitParams) {
|
|
2435
|
-
assign(
|
|
2656
|
+
assign(initParams, viewInitParams);
|
|
2436
2657
|
}
|
|
2437
2658
|
const sign = this.signature;
|
|
2438
|
-
|
|
2439
|
-
|
|
2659
|
+
const registered = getViewClass(viewClassName);
|
|
2660
|
+
if (registered) {
|
|
2661
|
+
this.doMountView(registered, initParams, node, sign);
|
|
2662
|
+
return;
|
|
2440
2663
|
}
|
|
2664
|
+
use(viewClassName, (ViewClass) => {
|
|
2665
|
+
if (sign !== this.signature) return;
|
|
2666
|
+
if (typeof ViewClass === "function") {
|
|
2667
|
+
const ViewClassTyped = ViewClass;
|
|
2668
|
+
registerViewClass(viewClassName, ViewClassTyped);
|
|
2669
|
+
this.doMountView(ViewClassTyped, initParams, node, sign);
|
|
2670
|
+
} else {
|
|
2671
|
+
const error = new Error(`Cannot load view: ${viewClassName}`);
|
|
2672
|
+
const errorHandler = config.error;
|
|
2673
|
+
if (errorHandler) {
|
|
2674
|
+
errorHandler(error);
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
});
|
|
2441
2678
|
}
|
|
2442
2679
|
/**
|
|
2443
2680
|
* Internal: actually mount the view after class is loaded.
|
|
@@ -2445,14 +2682,8 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2445
2682
|
doMountView(ViewClass, params, node, sign) {
|
|
2446
2683
|
if (sign !== this.signature) return;
|
|
2447
2684
|
const mixinCtors = View.prepare(ViewClass);
|
|
2448
|
-
const
|
|
2449
|
-
const view = new
|
|
2450
|
-
this.id,
|
|
2451
|
-
this,
|
|
2452
|
-
params,
|
|
2453
|
-
node,
|
|
2454
|
-
mixinCtors
|
|
2455
|
-
);
|
|
2685
|
+
const Ctor = ViewClass;
|
|
2686
|
+
const view = new Ctor(this.id, this, params, node, mixinCtors);
|
|
2456
2687
|
this.viewInstance = view;
|
|
2457
2688
|
view.signature = 1;
|
|
2458
2689
|
View.delegateEvents(view);
|
|
@@ -2533,7 +2764,9 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2533
2764
|
frame.unmountView();
|
|
2534
2765
|
removeFrame(targetId, wasCreated);
|
|
2535
2766
|
reInitFrameForCache(frame);
|
|
2536
|
-
frameCache.
|
|
2767
|
+
if (frameCache.length < MAX_FRAME_POOL) {
|
|
2768
|
+
frameCache.push(frame);
|
|
2769
|
+
}
|
|
2537
2770
|
const parent = frameRegistry.get(pId || "");
|
|
2538
2771
|
if (parent && parent.childrenMap[targetId]) {
|
|
2539
2772
|
Reflect.deleteProperty(parent.childrenMap, targetId);
|
|
@@ -2552,13 +2785,12 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2552
2785
|
const viewElements = rootEl.querySelectorAll(`[${LARK_VIEW}]`);
|
|
2553
2786
|
const frames = [];
|
|
2554
2787
|
viewElements.forEach((el) => {
|
|
2555
|
-
|
|
2556
|
-
if (
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
}
|
|
2788
|
+
if (!(el instanceof HTMLElement)) return;
|
|
2789
|
+
if (htmlElIsBound(el)) return;
|
|
2790
|
+
const elId = ensureElementId2(el);
|
|
2791
|
+
el.frameBound = 1;
|
|
2792
|
+
const viewPath = getAttribute(el, LARK_VIEW);
|
|
2793
|
+
frames.push([elId, viewPath]);
|
|
2562
2794
|
});
|
|
2563
2795
|
for (const [frameId, viewPath] of frames) {
|
|
2564
2796
|
this.mountFrame(frameId, viewPath);
|
|
@@ -2571,7 +2803,7 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2571
2803
|
*/
|
|
2572
2804
|
unmountZone(zoneId, _inner) {
|
|
2573
2805
|
for (const childId in this.childrenMap) {
|
|
2574
|
-
if (
|
|
2806
|
+
if (hasOwnProperty(this.childrenMap, childId)) {
|
|
2575
2807
|
if (!zoneId || childId !== zoneId) {
|
|
2576
2808
|
this.unmountFrame(childId);
|
|
2577
2809
|
}
|
|
@@ -2585,7 +2817,7 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2585
2817
|
children() {
|
|
2586
2818
|
const result = [];
|
|
2587
2819
|
for (const id in this.childrenMap) {
|
|
2588
|
-
if (
|
|
2820
|
+
if (hasOwnProperty(this.childrenMap, id)) {
|
|
2589
2821
|
result.push(id);
|
|
2590
2822
|
}
|
|
2591
2823
|
}
|
|
@@ -2612,14 +2844,10 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2612
2844
|
let result;
|
|
2613
2845
|
const view = this.view;
|
|
2614
2846
|
if (view && view.rendered) {
|
|
2615
|
-
const
|
|
2847
|
+
const lookup = view;
|
|
2848
|
+
const fn = lookup[name];
|
|
2616
2849
|
if (typeof fn === "function") {
|
|
2617
|
-
result = funcWithTry(
|
|
2618
|
-
fn,
|
|
2619
|
-
args || [],
|
|
2620
|
-
view,
|
|
2621
|
-
noop
|
|
2622
|
-
);
|
|
2850
|
+
result = funcWithTry(fn, args || [], view, noop);
|
|
2623
2851
|
}
|
|
2624
2852
|
} else {
|
|
2625
2853
|
const key = SPLITTER + name;
|
|
@@ -2642,6 +2870,25 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2642
2870
|
}
|
|
2643
2871
|
return result;
|
|
2644
2872
|
}
|
|
2873
|
+
/**
|
|
2874
|
+
* Type-safe variant of `invoke`.
|
|
2875
|
+
*
|
|
2876
|
+
* `invoke()` accepts any string and any args, which silently hides
|
|
2877
|
+
* mismatched call sites when a method gets renamed. `invokeTyped` carries
|
|
2878
|
+
* the view's method signature through TypeScript so the compiler catches
|
|
2879
|
+
* those mistakes:
|
|
2880
|
+
*
|
|
2881
|
+
* ```ts
|
|
2882
|
+
* type Home = View & { loadData(id: string): Promise<void> };
|
|
2883
|
+
* frame.invokeTyped<Home, "loadData">("loadData", ["user-1"]);
|
|
2884
|
+
* ```
|
|
2885
|
+
*
|
|
2886
|
+
* Behavior is identical to `invoke` at runtime — same defer / direct-call
|
|
2887
|
+
* paths — so it's a drop-in safer overload.
|
|
2888
|
+
*/
|
|
2889
|
+
invokeTyped(name, args) {
|
|
2890
|
+
return this.invoke(name, args);
|
|
2891
|
+
}
|
|
2645
2892
|
// ============================================================
|
|
2646
2893
|
// Static methods
|
|
2647
2894
|
// ============================================================
|
|
@@ -2653,8 +2900,25 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2653
2900
|
static getAll() {
|
|
2654
2901
|
return frameRegistry;
|
|
2655
2902
|
}
|
|
2656
|
-
/**
|
|
2657
|
-
|
|
2903
|
+
/**
|
|
2904
|
+
* Returns the existing root frame, or `undefined` if none has been created.
|
|
2905
|
+
* Pure getter — never creates a Frame, never touches the DOM.
|
|
2906
|
+
*
|
|
2907
|
+
* Use `Frame.createRoot(id)` to create the root explicitly during framework
|
|
2908
|
+
* boot. For Micro-Frontend hosts that own multiple independent containers,
|
|
2909
|
+
* use `new Frame(containerId)` directly so each MF mount has its own root.
|
|
2910
|
+
*/
|
|
2911
|
+
static getRoot() {
|
|
2912
|
+
return rootFrame;
|
|
2913
|
+
}
|
|
2914
|
+
/**
|
|
2915
|
+
* Create (or return) the singleton root frame for this app.
|
|
2916
|
+
*
|
|
2917
|
+
* Idempotent: subsequent calls always return the original root regardless
|
|
2918
|
+
* of `rootId` — so passing a different id later is silently ignored.
|
|
2919
|
+
* `Framework.boot()` is the canonical caller; user code rarely needs this.
|
|
2920
|
+
*/
|
|
2921
|
+
static createRoot(rootId) {
|
|
2658
2922
|
if (!rootFrame) {
|
|
2659
2923
|
rootId = rootId || "root";
|
|
2660
2924
|
let rootElement = document.getElementById(rootId);
|
|
@@ -2666,6 +2930,17 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2666
2930
|
}
|
|
2667
2931
|
return rootFrame;
|
|
2668
2932
|
}
|
|
2933
|
+
/**
|
|
2934
|
+
* @deprecated Use `Frame.getRoot()` for read-only access or
|
|
2935
|
+
* `Frame.createRoot(id)` to create the root explicitly. The single-method
|
|
2936
|
+
* `root()` blurred the distinction and was a common source of bugs in
|
|
2937
|
+
* Micro-Frontend hosts.
|
|
2938
|
+
*
|
|
2939
|
+
* Kept for backward compatibility — behavior unchanged.
|
|
2940
|
+
*/
|
|
2941
|
+
static root(rootId) {
|
|
2942
|
+
return _Frame.createRoot(rootId);
|
|
2943
|
+
}
|
|
2669
2944
|
/** Bind event listener (static) */
|
|
2670
2945
|
static on(event, handler) {
|
|
2671
2946
|
staticEmitter.on(event, handler);
|
|
@@ -2681,6 +2956,9 @@ var Frame = class _Frame extends EventEmitter {
|
|
|
2681
2956
|
staticEmitter.fire(event, data);
|
|
2682
2957
|
}
|
|
2683
2958
|
};
|
|
2959
|
+
function htmlElIsBound(element) {
|
|
2960
|
+
return !!element.frameBound;
|
|
2961
|
+
}
|
|
2684
2962
|
function ensureElementId2(element) {
|
|
2685
2963
|
const id = element.getAttribute("id");
|
|
2686
2964
|
if (id) return id;
|
|
@@ -2710,8 +2988,8 @@ function notifyCreated(frameInstance) {
|
|
|
2710
2988
|
const pId = frameInstance.parentId;
|
|
2711
2989
|
if (pId) {
|
|
2712
2990
|
const parent = frameRegistry.get(pId);
|
|
2713
|
-
if (parent && !parent.readyMap
|
|
2714
|
-
parent.readyMap
|
|
2991
|
+
if (parent && !parent.readyMap.has(frameInstance.id)) {
|
|
2992
|
+
parent.readyMap.add(frameInstance.id);
|
|
2715
2993
|
parent.readyCount++;
|
|
2716
2994
|
notifyCreated(parent);
|
|
2717
2995
|
}
|
|
@@ -2726,9 +3004,9 @@ function notifyAlter(frameInstance, data) {
|
|
|
2726
3004
|
const pId = frameInstance.parentId;
|
|
2727
3005
|
if (pId) {
|
|
2728
3006
|
const parent = frameRegistry.get(pId);
|
|
2729
|
-
if (parent && parent.readyMap
|
|
3007
|
+
if (parent && parent.readyMap.has(frameInstance.id)) {
|
|
2730
3008
|
parent.readyCount--;
|
|
2731
|
-
|
|
3009
|
+
parent.readyMap.delete(frameInstance.id);
|
|
2732
3010
|
notifyAlter(parent, data);
|
|
2733
3011
|
}
|
|
2734
3012
|
}
|
|
@@ -2741,7 +3019,7 @@ function reInitFrame(frame, id, parentId) {
|
|
|
2741
3019
|
frame["childrenCount"] = 0;
|
|
2742
3020
|
frame["readyCount"] = 0;
|
|
2743
3021
|
frame["signature"] = 1;
|
|
2744
|
-
frame["readyMap"] =
|
|
3022
|
+
frame["readyMap"] = /* @__PURE__ */ new Set();
|
|
2745
3023
|
frame["invokeList"] = [];
|
|
2746
3024
|
frameRegistry.set(id, frame);
|
|
2747
3025
|
}
|
|
@@ -2749,7 +3027,7 @@ function reInitFrameForCache(frame) {
|
|
|
2749
3027
|
Reflect.set(frame, "id", "");
|
|
2750
3028
|
frame["_parentId"] = void 0;
|
|
2751
3029
|
frame["childrenMap"] = {};
|
|
2752
|
-
frame["readyMap"] =
|
|
3030
|
+
frame["readyMap"] = /* @__PURE__ */ new Set();
|
|
2753
3031
|
}
|
|
2754
3032
|
function translateQuery(pId, src, params) {
|
|
2755
3033
|
const parentFrame = frameRegistry.get(pId);
|
|
@@ -2759,22 +3037,138 @@ function translateQuery(pId, src, params) {
|
|
|
2759
3037
|
if (!parentRefData) return;
|
|
2760
3038
|
if (src.indexOf(SPLITTER) > 0) {
|
|
2761
3039
|
translateData(parentRefData, params);
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
);
|
|
3040
|
+
const paramsRec = params;
|
|
3041
|
+
const splitterValue = paramsRec[SPLITTER];
|
|
3042
|
+
if (splitterValue && typeof splitterValue === "object") {
|
|
3043
|
+
assign(params, splitterValue);
|
|
2767
3044
|
Reflect.deleteProperty(params, SPLITTER);
|
|
2768
3045
|
}
|
|
2769
3046
|
}
|
|
2770
3047
|
}
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
3048
|
+
|
|
3049
|
+
// src/cross-site.ts
|
|
3050
|
+
var preparePromises = {};
|
|
3051
|
+
var projectsMap = null;
|
|
3052
|
+
function loadRemoteView(viewPath, bizCode) {
|
|
3053
|
+
const crossConfigs = config.crossConfigs || window.crossConfigs;
|
|
3054
|
+
const currentName = config.projectName || "";
|
|
3055
|
+
const slashIndex = viewPath.indexOf("/");
|
|
3056
|
+
const projectName = slashIndex > -1 ? viewPath.substring(0, slashIndex) : viewPath;
|
|
3057
|
+
if (projectName === currentName) return Promise.resolve();
|
|
3058
|
+
if (!preparePromises[projectName]) {
|
|
3059
|
+
if (!projectsMap) {
|
|
3060
|
+
const map = toMap(crossConfigs || [], "projectName");
|
|
3061
|
+
projectsMap = map;
|
|
3062
|
+
}
|
|
3063
|
+
const info = projectsMap[projectName];
|
|
3064
|
+
if (!info) {
|
|
3065
|
+
return Promise.reject(
|
|
3066
|
+
new Error(`Cannot find ${projectName} from crossConfigs`)
|
|
3067
|
+
);
|
|
3068
|
+
}
|
|
3069
|
+
preparePromises[projectName] = use(`${projectName}/prepare`).then((modules) => {
|
|
3070
|
+
let mod = modules[0];
|
|
3071
|
+
if (mod && typeof mod === "object" && mod !== null) {
|
|
3072
|
+
const rec = mod;
|
|
3073
|
+
if (rec["__esModule"]) {
|
|
3074
|
+
mod = rec["default"];
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
if (typeof mod === "function") {
|
|
3078
|
+
return mod({ bizCode });
|
|
3079
|
+
}
|
|
3080
|
+
return void 0;
|
|
3081
|
+
}).catch((err) => {
|
|
3082
|
+
Reflect.deleteProperty(preparePromises, projectName);
|
|
3083
|
+
throw err;
|
|
3084
|
+
});
|
|
2776
3085
|
}
|
|
3086
|
+
return preparePromises[projectName];
|
|
2777
3087
|
}
|
|
3088
|
+
function resetProjectsMap() {
|
|
3089
|
+
projectsMap = null;
|
|
3090
|
+
}
|
|
3091
|
+
var skeletonTemplate = (data, viewId) => {
|
|
3092
|
+
let skeletonHtml = "<div>Loading...</div>";
|
|
3093
|
+
if (data && typeof data === "object") {
|
|
3094
|
+
const candidate = data.skeleton;
|
|
3095
|
+
if (typeof candidate === "string") skeletonHtml = candidate;
|
|
3096
|
+
}
|
|
3097
|
+
return `<div id="mf_${viewId}">${skeletonHtml}</div>`;
|
|
3098
|
+
};
|
|
3099
|
+
var CrossSite = View.extend({
|
|
3100
|
+
/** Skeleton template renders loading state + child container */
|
|
3101
|
+
template: skeletonTemplate,
|
|
3102
|
+
init(params) {
|
|
3103
|
+
this.$sign = 0;
|
|
3104
|
+
this.on("destroy", () => {
|
|
3105
|
+
this.$sign = -1;
|
|
3106
|
+
});
|
|
3107
|
+
this.assign?.(params);
|
|
3108
|
+
},
|
|
3109
|
+
assign(data) {
|
|
3110
|
+
this.$view = typeof data["view"] === "string" ? data["view"] : "";
|
|
3111
|
+
const nested = data["params"];
|
|
3112
|
+
const nestedParams = nested && typeof nested === "object" ? nested : {};
|
|
3113
|
+
this.$params = { ...data, ...nestedParams };
|
|
3114
|
+
this.updater.set({
|
|
3115
|
+
skeleton: data["skeleton"],
|
|
3116
|
+
skeletonParams: data["skeletonParams"] || {},
|
|
3117
|
+
bizCode: data["bizCode"]
|
|
3118
|
+
});
|
|
3119
|
+
if (this.$sign > 0) {
|
|
3120
|
+
this.updateView();
|
|
3121
|
+
}
|
|
3122
|
+
return false;
|
|
3123
|
+
},
|
|
3124
|
+
async updateView() {
|
|
3125
|
+
const sign = ++this.$sign;
|
|
3126
|
+
const stored = this.updater.get();
|
|
3127
|
+
const bizCode = stored.bizCode;
|
|
3128
|
+
try {
|
|
3129
|
+
await loadRemoteView(this.$view, bizCode);
|
|
3130
|
+
} catch (ex) {
|
|
3131
|
+
const node = document.getElementById("mf_" + this.id);
|
|
3132
|
+
if (node) {
|
|
3133
|
+
const err = ex instanceof Error ? ex : new Error(String(ex));
|
|
3134
|
+
node.innerHTML = err.message || String(err);
|
|
3135
|
+
}
|
|
3136
|
+
}
|
|
3137
|
+
if (this.$sign !== sign) return;
|
|
3138
|
+
const mf = Frame.get("mf_" + this.id);
|
|
3139
|
+
const parsedNew = parseUri(this.$view);
|
|
3140
|
+
const newPath = parsedNew.path;
|
|
3141
|
+
const oldPath = mf?.viewPath ? parseUri(mf.viewPath).path : "";
|
|
3142
|
+
const view = mf?.view;
|
|
3143
|
+
if (newPath === oldPath && view && typeof view.assign === "function") {
|
|
3144
|
+
const result = funcWithTry(view.assign, [this.$params], view, noop);
|
|
3145
|
+
if (result) {
|
|
3146
|
+
view.render();
|
|
3147
|
+
}
|
|
3148
|
+
return;
|
|
3149
|
+
}
|
|
3150
|
+
const owner = this.owner;
|
|
3151
|
+
if (owner && typeof owner !== "number") {
|
|
3152
|
+
owner.mountFrame("mf_" + this.id, this.$view, this.$params);
|
|
3153
|
+
}
|
|
3154
|
+
},
|
|
3155
|
+
render() {
|
|
3156
|
+
const params = this.$params;
|
|
3157
|
+
this.updater.digest({
|
|
3158
|
+
skeleton: params?.["skeleton"]
|
|
3159
|
+
});
|
|
3160
|
+
this.updateView();
|
|
3161
|
+
},
|
|
3162
|
+
/**
|
|
3163
|
+
* Invoke a method on the remote view.
|
|
3164
|
+
* Usage: mf.invoke('callView', methodName, ...args)
|
|
3165
|
+
*/
|
|
3166
|
+
callView(name, ...args) {
|
|
3167
|
+
const mf = Frame.get("mf_" + this.id);
|
|
3168
|
+
return mf?.invoke(name, args);
|
|
3169
|
+
}
|
|
3170
|
+
});
|
|
3171
|
+
var cross_site_default = CrossSite;
|
|
2778
3172
|
|
|
2779
3173
|
// src/service.ts
|
|
2780
3174
|
var Payload = class {
|
|
@@ -2962,29 +3356,31 @@ var Service = class {
|
|
|
2962
3356
|
* Get metadata for an API endpoint.
|
|
2963
3357
|
*/
|
|
2964
3358
|
static meta(attrs) {
|
|
2965
|
-
const name = typeof attrs === "string" ? attrs : attrs["name"];
|
|
2966
|
-
|
|
3359
|
+
const name = typeof attrs === "string" ? attrs : String(attrs["name"] ?? "");
|
|
3360
|
+
const known = this._metaList[name];
|
|
3361
|
+
if (known) return known;
|
|
3362
|
+
return attrs;
|
|
2967
3363
|
}
|
|
2968
3364
|
/**
|
|
2969
3365
|
* Create a Payload for an API request.
|
|
2970
3366
|
*/
|
|
2971
3367
|
static create(attrs) {
|
|
2972
3368
|
const meta = this.meta(attrs);
|
|
2973
|
-
const cache = attrs["cache"]
|
|
3369
|
+
const cache = toCacheValue(attrs["cache"]) || meta.cache || 0;
|
|
2974
3370
|
const entity = new Payload();
|
|
2975
3371
|
entity.set(meta);
|
|
2976
3372
|
entity.cacheInfo = {
|
|
2977
3373
|
name: meta.name,
|
|
2978
|
-
after: meta.after,
|
|
2979
|
-
cleans: meta.cleanKeys,
|
|
3374
|
+
after: typeof meta.after === "function" ? meta.after : void 0,
|
|
3375
|
+
cleans: typeof meta.cleanKeys === "string" ? meta.cleanKeys : void 0,
|
|
2980
3376
|
key: cache ? defaultCacheKey(meta, attrs) : "",
|
|
2981
3377
|
time: 0
|
|
2982
3378
|
};
|
|
2983
|
-
if (
|
|
3379
|
+
if (attrs !== null) {
|
|
2984
3380
|
entity.set(attrs);
|
|
2985
3381
|
}
|
|
2986
3382
|
const before = meta.before;
|
|
2987
|
-
if (before) {
|
|
3383
|
+
if (typeof before === "function") {
|
|
2988
3384
|
funcWithTry(before, [entity], entity, noop);
|
|
2989
3385
|
}
|
|
2990
3386
|
this._staticEmitter.fire("begin", { payload: entity });
|
|
@@ -3010,7 +3406,7 @@ var Service = class {
|
|
|
3010
3406
|
*/
|
|
3011
3407
|
static cached(attrs) {
|
|
3012
3408
|
const meta = this.meta(attrs);
|
|
3013
|
-
const cache = attrs["cache"]
|
|
3409
|
+
const cache = toCacheValue(attrs["cache"]) || meta.cache || 0;
|
|
3014
3410
|
let cacheKey = "";
|
|
3015
3411
|
if (cache) {
|
|
3016
3412
|
cacheKey = defaultCacheKey(meta, attrs);
|
|
@@ -3018,7 +3414,8 @@ var Service = class {
|
|
|
3018
3414
|
if (cacheKey) {
|
|
3019
3415
|
const info = this._pendingCacheKeys[cacheKey];
|
|
3020
3416
|
if (info) {
|
|
3021
|
-
|
|
3417
|
+
const entity = info.entity;
|
|
3418
|
+
return entity instanceof Payload ? entity : void 0;
|
|
3022
3419
|
}
|
|
3023
3420
|
const cached = this._payloadCache.get(cacheKey);
|
|
3024
3421
|
if (cached && cached.cacheInfo) {
|
|
@@ -3035,17 +3432,14 @@ var Service = class {
|
|
|
3035
3432
|
* Clear cached payloads by endpoint name.
|
|
3036
3433
|
*/
|
|
3037
3434
|
static clear(names) {
|
|
3038
|
-
const
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
nameSet[n] = 1;
|
|
3042
|
-
}
|
|
3435
|
+
const nameSet = new Set(
|
|
3436
|
+
(typeof names === "string" ? names : names.join(",")).split(",")
|
|
3437
|
+
);
|
|
3043
3438
|
const keysToDelete = [];
|
|
3044
3439
|
this._payloadCache.forEach((payload) => {
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
}
|
|
3440
|
+
const info = payload?.cacheInfo;
|
|
3441
|
+
if (info && info.key && nameSet.has(info.name)) {
|
|
3442
|
+
keysToDelete.push(info.key);
|
|
3049
3443
|
}
|
|
3050
3444
|
});
|
|
3051
3445
|
for (const key of keysToDelete) {
|
|
@@ -3064,12 +3458,23 @@ var Service = class {
|
|
|
3064
3458
|
}
|
|
3065
3459
|
/**
|
|
3066
3460
|
* Create a new Service subclass with a custom sync function.
|
|
3067
|
-
*
|
|
3068
|
-
*
|
|
3461
|
+
*
|
|
3462
|
+
* Each subclass gets its OWN copies of every per-type static field
|
|
3463
|
+
* (`_metaList`, `_payloadCache`, `_pendingCacheKeys`, `_syncFn`,
|
|
3464
|
+
* `_staticEmitter`, `_cacheMax`, `_cacheBuffer`) via `static override`.
|
|
3465
|
+
* This is intentional: it ensures that endpoint metadata, cache state,
|
|
3466
|
+
* in-flight dedup keys, and event subscribers are fully isolated between
|
|
3467
|
+
* different Service types, even when one extends another.
|
|
3468
|
+
*
|
|
3469
|
+
* **Do not refactor these `static override` declarations away** — sharing
|
|
3470
|
+
* them through prototype inheritance would let endpoints registered on one
|
|
3471
|
+
* subclass leak into another, and the LFU cache evictions of one type
|
|
3472
|
+
* would race with those of another.
|
|
3069
3473
|
*/
|
|
3070
3474
|
static extend(newSyncFn, newCacheMax, newCacheBuffer) {
|
|
3071
3475
|
const ParentService = this;
|
|
3072
3476
|
class ChildService extends ParentService {
|
|
3477
|
+
// Intentionally per-subclass — see Service.extend doc.
|
|
3073
3478
|
static _metaList = {};
|
|
3074
3479
|
static _payloadCache = new Cache({
|
|
3075
3480
|
maxSize: newCacheMax || ParentService._cacheMax,
|
|
@@ -3084,18 +3489,34 @@ var Service = class {
|
|
|
3084
3489
|
return ChildService;
|
|
3085
3490
|
}
|
|
3086
3491
|
};
|
|
3492
|
+
var metaJsonCache = /* @__PURE__ */ new WeakMap();
|
|
3493
|
+
function getMetaJson(meta) {
|
|
3494
|
+
let cached = metaJsonCache.get(meta);
|
|
3495
|
+
if (cached === void 0) {
|
|
3496
|
+
cached = JSON.stringify(meta);
|
|
3497
|
+
metaJsonCache.set(meta, cached);
|
|
3498
|
+
}
|
|
3499
|
+
return cached;
|
|
3500
|
+
}
|
|
3087
3501
|
function defaultCacheKey(meta, attrs) {
|
|
3088
|
-
return JSON.stringify(attrs) + SPLITTER +
|
|
3502
|
+
return JSON.stringify(attrs) + SPLITTER + getMetaJson(meta);
|
|
3503
|
+
}
|
|
3504
|
+
function toCacheValue(v) {
|
|
3505
|
+
if (typeof v === "number") return v | 0;
|
|
3506
|
+
if (typeof v === "string") {
|
|
3507
|
+
const n = Number(v);
|
|
3508
|
+
return Number.isFinite(n) ? n | 0 : 0;
|
|
3509
|
+
}
|
|
3510
|
+
return 0;
|
|
3089
3511
|
}
|
|
3090
3512
|
function serviceSend(service, attrs, done, flag, save) {
|
|
3091
|
-
if (service
|
|
3092
|
-
if (service
|
|
3093
|
-
service
|
|
3094
|
-
|
|
3095
|
-
);
|
|
3513
|
+
if (service.destroyed) return;
|
|
3514
|
+
if (service.busy) {
|
|
3515
|
+
const queued = () => serviceSend(service, attrs, done, flag, save);
|
|
3516
|
+
service.enqueue(queued);
|
|
3096
3517
|
return;
|
|
3097
3518
|
}
|
|
3098
|
-
service
|
|
3519
|
+
service.busy = 1;
|
|
3099
3520
|
let attrList;
|
|
3100
3521
|
if (typeof attrs === "string") {
|
|
3101
3522
|
attrList = [{ name: attrs }];
|
|
@@ -3120,10 +3541,10 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3120
3541
|
newPayload = true;
|
|
3121
3542
|
staticEmitter2.fire("done", { payload });
|
|
3122
3543
|
}
|
|
3123
|
-
if (!service
|
|
3544
|
+
if (!service.destroyed) {
|
|
3124
3545
|
const finish = requestCount === total;
|
|
3125
3546
|
if (finish) {
|
|
3126
|
-
service
|
|
3547
|
+
service.busy = 0;
|
|
3127
3548
|
if (flag === FETCH_FLAGS_ALL) {
|
|
3128
3549
|
doneArr[0] = errorArgs;
|
|
3129
3550
|
funcWithTry(done, doneArr, service, noop);
|
|
@@ -3140,10 +3561,7 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3140
3561
|
for (const attr of attrList) {
|
|
3141
3562
|
if (!attr) continue;
|
|
3142
3563
|
const attrObj = typeof attr === "string" ? { name: attr } : attr;
|
|
3143
|
-
const payloadInfo = service.type.get(
|
|
3144
|
-
attrObj,
|
|
3145
|
-
save
|
|
3146
|
-
);
|
|
3564
|
+
const payloadInfo = service.type.get(attrObj, save);
|
|
3147
3565
|
const payloadEntity = payloadInfo.entity;
|
|
3148
3566
|
const cacheKey = payloadEntity.cacheInfo?.key || "";
|
|
3149
3567
|
const complete = remoteComplete.bind(null, requestCount++);
|
|
@@ -3157,15 +3575,13 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3157
3575
|
const cacheComplete = () => {
|
|
3158
3576
|
const list = pendingCacheKeys[cacheKey];
|
|
3159
3577
|
const entity = list.entity;
|
|
3160
|
-
if (entity.cacheInfo) {
|
|
3578
|
+
if (entity instanceof Payload && entity.cacheInfo) {
|
|
3161
3579
|
entity.cacheInfo.time = now();
|
|
3580
|
+
internals.payloadCache.set(cacheKey, entity);
|
|
3162
3581
|
}
|
|
3163
|
-
internals.payloadCache.set(cacheKey, entity);
|
|
3164
3582
|
Reflect.deleteProperty(pendingCacheKeys, cacheKey);
|
|
3165
3583
|
for (const cb of list) {
|
|
3166
|
-
if (typeof cb === "function")
|
|
3167
|
-
cb();
|
|
3168
|
-
}
|
|
3584
|
+
if (typeof cb === "function") cb();
|
|
3169
3585
|
}
|
|
3170
3586
|
};
|
|
3171
3587
|
syncFn(payloadEntity, cacheComplete);
|
|
@@ -3178,13 +3594,32 @@ function serviceSend(service, attrs, done, flag, save) {
|
|
|
3178
3594
|
}
|
|
3179
3595
|
}
|
|
3180
3596
|
|
|
3181
|
-
// src/frame-
|
|
3182
|
-
var
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3597
|
+
// src/frame-visual.ts
|
|
3598
|
+
var FrameVisualBridge = {
|
|
3599
|
+
MSG_PING: "LARK_VIS_PING",
|
|
3600
|
+
MSG_PONG: "LARK_VIS_PONG",
|
|
3601
|
+
MSG_REQUEST_TREE: "LARK_VIS_REQUEST_TREE",
|
|
3602
|
+
MSG_TREE: "LARK_VIS_TREE",
|
|
3603
|
+
MSG_TREE_DELTA: "LARK_VIS_TREE_DELTA"
|
|
3604
|
+
};
|
|
3187
3605
|
function serializeView(view) {
|
|
3606
|
+
const evtMap = view.eventObjectMap;
|
|
3607
|
+
const eventMethodKeys = evtMap ? Object.keys(evtMap) : [];
|
|
3608
|
+
const resourceKeys = view.resources ? Object.keys(view.resources) : [];
|
|
3609
|
+
const lookup = view;
|
|
3610
|
+
const hasAssign = typeof lookup["assign"] === "function";
|
|
3611
|
+
let updaterData = null;
|
|
3612
|
+
try {
|
|
3613
|
+
const ref = view.updater?.refData;
|
|
3614
|
+
if (ref && typeof ref === "object") {
|
|
3615
|
+
updaterData = {};
|
|
3616
|
+
for (const k of Object.keys(ref)) {
|
|
3617
|
+
const v = ref[k];
|
|
3618
|
+
updaterData[k] = v === null || typeof v !== "object" ? v : `[${typeof v}]`;
|
|
3619
|
+
}
|
|
3620
|
+
}
|
|
3621
|
+
} catch {
|
|
3622
|
+
}
|
|
3188
3623
|
return {
|
|
3189
3624
|
id: view.id,
|
|
3190
3625
|
rendered: !!view.rendered,
|
|
@@ -3195,7 +3630,11 @@ function serializeView(view) {
|
|
|
3195
3630
|
keys: view.locationObserved.keys,
|
|
3196
3631
|
observePath: view.locationObserved.observePath
|
|
3197
3632
|
},
|
|
3198
|
-
hasTemplate: !!view.template
|
|
3633
|
+
hasTemplate: !!view.template,
|
|
3634
|
+
eventMethodKeys,
|
|
3635
|
+
resourceKeys,
|
|
3636
|
+
hasAssign,
|
|
3637
|
+
updaterData
|
|
3199
3638
|
};
|
|
3200
3639
|
}
|
|
3201
3640
|
function serializeFrame(frameId) {
|
|
@@ -3223,7 +3662,10 @@ function serializeFrame(frameId) {
|
|
|
3223
3662
|
};
|
|
3224
3663
|
}
|
|
3225
3664
|
function serializeFrameTree() {
|
|
3226
|
-
const root = Frame.
|
|
3665
|
+
const root = Frame.getRoot();
|
|
3666
|
+
if (!root) {
|
|
3667
|
+
return { root: null, totalFrames: 0, timestamp: Date.now(), rootId: "" };
|
|
3668
|
+
}
|
|
3227
3669
|
const rootNode = serializeFrame(root.id);
|
|
3228
3670
|
let totalFrames = 0;
|
|
3229
3671
|
const countFrames = (node) => {
|
|
@@ -3251,19 +3693,22 @@ function installFrameVisualizerBridge() {
|
|
|
3251
3693
|
const data = event.data;
|
|
3252
3694
|
if (!data || typeof data !== "object") return;
|
|
3253
3695
|
const type = data.type;
|
|
3254
|
-
if (type === MSG_PING) {
|
|
3696
|
+
if (type === FrameVisualBridge.MSG_PING) {
|
|
3255
3697
|
const source = event.source;
|
|
3256
3698
|
if (source) {
|
|
3257
|
-
source.postMessage(
|
|
3699
|
+
source.postMessage(
|
|
3700
|
+
{ type: FrameVisualBridge.MSG_PONG },
|
|
3701
|
+
{ targetOrigin: "*" }
|
|
3702
|
+
);
|
|
3258
3703
|
}
|
|
3259
3704
|
return;
|
|
3260
3705
|
}
|
|
3261
|
-
if (type === MSG_REQUEST_TREE) {
|
|
3706
|
+
if (type === FrameVisualBridge.MSG_REQUEST_TREE) {
|
|
3262
3707
|
const tree = serializeFrameTree();
|
|
3263
3708
|
const source = event.source;
|
|
3264
3709
|
if (source) {
|
|
3265
3710
|
source.postMessage(
|
|
3266
|
-
{ type: MSG_TREE, data: tree },
|
|
3711
|
+
{ type: FrameVisualBridge.MSG_TREE, data: tree },
|
|
3267
3712
|
{ targetOrigin: "*" }
|
|
3268
3713
|
);
|
|
3269
3714
|
}
|
|
@@ -3282,18 +3727,14 @@ function pushTreeUpdate() {
|
|
|
3282
3727
|
const treeJson = JSON.stringify(tree);
|
|
3283
3728
|
if (treeJson !== lastTreeJson) {
|
|
3284
3729
|
lastTreeJson = treeJson;
|
|
3285
|
-
window.parent.postMessage(
|
|
3730
|
+
window.parent.postMessage(
|
|
3731
|
+
{ type: FrameVisualBridge.MSG_TREE_DELTA, data: tree },
|
|
3732
|
+
"*"
|
|
3733
|
+
);
|
|
3286
3734
|
}
|
|
3287
3735
|
}
|
|
3288
3736
|
|
|
3289
3737
|
// src/framework.ts
|
|
3290
|
-
var config = {
|
|
3291
|
-
rootId: "root",
|
|
3292
|
-
hashbang: "#!",
|
|
3293
|
-
error: (error) => {
|
|
3294
|
-
throw error;
|
|
3295
|
-
}
|
|
3296
|
-
};
|
|
3297
3738
|
var booted3 = false;
|
|
3298
3739
|
var taskList = [];
|
|
3299
3740
|
var taskIndex = 0;
|
|
@@ -3342,6 +3783,9 @@ function task(fn, args, context) {
|
|
|
3342
3783
|
}
|
|
3343
3784
|
}
|
|
3344
3785
|
var dispatcherUpdateTag = 0;
|
|
3786
|
+
function isThenable(value) {
|
|
3787
|
+
return !!value && (typeof value === "object" || typeof value === "function") && typeof value.then === "function";
|
|
3788
|
+
}
|
|
3345
3789
|
function viewIsObserveChanged(view) {
|
|
3346
3790
|
const loc = view.locationObserved;
|
|
3347
3791
|
let result = false;
|
|
@@ -3355,7 +3799,7 @@ function viewIsObserveChanged(view) {
|
|
|
3355
3799
|
const changedParams = lastChanged2?.params;
|
|
3356
3800
|
if (changedParams) {
|
|
3357
3801
|
for (const key of loc.keys) {
|
|
3358
|
-
result =
|
|
3802
|
+
result = hasOwnProperty(changedParams, key);
|
|
3359
3803
|
if (result) break;
|
|
3360
3804
|
}
|
|
3361
3805
|
}
|
|
@@ -3367,48 +3811,59 @@ function stateIsObserveChanged(view, stateKeys) {
|
|
|
3367
3811
|
const observedKeys = view.observedStateKeys;
|
|
3368
3812
|
if (!observedKeys) return false;
|
|
3369
3813
|
for (const key of observedKeys) {
|
|
3370
|
-
if (has(
|
|
3814
|
+
if (stateKeys.has(key)) return true;
|
|
3371
3815
|
}
|
|
3372
3816
|
return false;
|
|
3373
3817
|
}
|
|
3374
3818
|
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
|
-
|
|
3819
|
+
const stack = [frame];
|
|
3820
|
+
const drain = (s) => {
|
|
3821
|
+
while (s.length > 0) {
|
|
3822
|
+
const current = s.pop();
|
|
3823
|
+
const tagged = current;
|
|
3824
|
+
const view = current.view;
|
|
3825
|
+
if (!view || tagged.dispatcherUpdateTag === dispatcherUpdateTag || view.signature <= 1) {
|
|
3826
|
+
continue;
|
|
3827
|
+
}
|
|
3828
|
+
tagged.dispatcherUpdateTag = dispatcherUpdateTag;
|
|
3829
|
+
const isChanged = stateKeys ? stateIsObserveChanged(view, stateKeys) : viewIsObserveChanged(view);
|
|
3830
|
+
let renderPromise;
|
|
3831
|
+
if (isChanged) {
|
|
3832
|
+
const renderResult = funcWithTry(
|
|
3833
|
+
view.renderMethod ?? view.render,
|
|
3834
|
+
[],
|
|
3835
|
+
view,
|
|
3836
|
+
noop
|
|
3837
|
+
);
|
|
3838
|
+
if (isThenable(renderResult)) {
|
|
3839
|
+
renderPromise = renderResult;
|
|
3840
|
+
}
|
|
3841
|
+
}
|
|
3842
|
+
const children = current.children();
|
|
3843
|
+
if (renderPromise) {
|
|
3844
|
+
renderPromise.then(() => {
|
|
3845
|
+
const subStack = [];
|
|
3846
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
3847
|
+
const child = Frame.get(children[i]);
|
|
3848
|
+
if (child) subStack.push(child);
|
|
3849
|
+
}
|
|
3850
|
+
drain(subStack);
|
|
3851
|
+
});
|
|
3852
|
+
} else {
|
|
3853
|
+
for (let i = children.length - 1; i >= 0; i--) {
|
|
3854
|
+
const child = Frame.get(children[i]);
|
|
3855
|
+
if (child) s.push(child);
|
|
3856
|
+
}
|
|
3400
3857
|
}
|
|
3401
3858
|
}
|
|
3402
3859
|
};
|
|
3403
|
-
|
|
3404
|
-
renderPromise.then(recurse);
|
|
3405
|
-
} else {
|
|
3406
|
-
recurse();
|
|
3407
|
-
}
|
|
3860
|
+
drain(stack);
|
|
3408
3861
|
}
|
|
3409
3862
|
function dispatcherNotifyChange(e) {
|
|
3410
|
-
const rootFrame2 = Frame.
|
|
3411
|
-
|
|
3863
|
+
const rootFrame2 = Frame.getRoot();
|
|
3864
|
+
if (!rootFrame2) return;
|
|
3865
|
+
const routeEvent = e;
|
|
3866
|
+
const view = routeEvent.view;
|
|
3412
3867
|
if (view) {
|
|
3413
3868
|
const viewPath = typeof view === "object" && view !== null ? String(view.to || "") : String(view);
|
|
3414
3869
|
rootFrame2.mountView(viewPath);
|
|
@@ -3425,19 +3880,6 @@ function dispatchEvent(target, eventType, eventInit) {
|
|
|
3425
3880
|
});
|
|
3426
3881
|
target.dispatchEvent(event);
|
|
3427
3882
|
}
|
|
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
3883
|
var WAIT_OK = 1;
|
|
3442
3884
|
var WAIT_TIMEOUT_OR_NOT_FOUND = 0;
|
|
3443
3885
|
function waitZoneViewsRendered(viewId, timeout) {
|
|
@@ -3460,12 +3902,27 @@ function waitZoneViewsRendered(viewId, timeout) {
|
|
|
3460
3902
|
setTimeout(check, 9);
|
|
3461
3903
|
});
|
|
3462
3904
|
}
|
|
3905
|
+
function getConfigImpl(key) {
|
|
3906
|
+
if (key === void 0) return config;
|
|
3907
|
+
return config[key];
|
|
3908
|
+
}
|
|
3463
3909
|
var Framework = {
|
|
3464
3910
|
// ============================================================
|
|
3465
3911
|
// Lifecycle
|
|
3466
3912
|
// ============================================================
|
|
3913
|
+
/** Read framework configuration. See `FrameworkInterface.getConfig`. */
|
|
3914
|
+
getConfig: getConfigImpl,
|
|
3915
|
+
/**
|
|
3916
|
+
* Merge a patch into framework configuration. See `FrameworkInterface.setConfig`.
|
|
3917
|
+
*/
|
|
3918
|
+
setConfig(patch) {
|
|
3919
|
+
if (patch && typeof patch === "object") {
|
|
3920
|
+
assign(config, patch);
|
|
3921
|
+
}
|
|
3922
|
+
return config;
|
|
3923
|
+
},
|
|
3467
3924
|
/**
|
|
3468
|
-
*
|
|
3925
|
+
* @deprecated Use `getConfig()` / `setConfig()`. Behavior unchanged.
|
|
3469
3926
|
*/
|
|
3470
3927
|
config(cfg) {
|
|
3471
3928
|
if (!cfg) {
|
|
@@ -3486,17 +3943,17 @@ var Framework = {
|
|
|
3486
3943
|
}
|
|
3487
3944
|
Router._setConfig(config);
|
|
3488
3945
|
EventDelegator.setFrameGetter((id) => Frame.get(id));
|
|
3489
|
-
Router.on(
|
|
3946
|
+
Router.on(RouterEvents.CHANGED, (data) => {
|
|
3490
3947
|
if (data) dispatcherNotifyChange(data);
|
|
3491
3948
|
});
|
|
3492
|
-
State.on(
|
|
3949
|
+
State.on(RouterEvents.CHANGED, (data) => {
|
|
3493
3950
|
if (data) dispatcherNotifyChange(data);
|
|
3494
3951
|
});
|
|
3495
3952
|
booted3 = true;
|
|
3496
3953
|
markBooted();
|
|
3497
3954
|
markRouterBooted();
|
|
3498
3955
|
installFrameVisualizerBridge();
|
|
3499
|
-
const rootFrame2 = Frame.
|
|
3956
|
+
const rootFrame2 = Frame.createRoot(config.rootId);
|
|
3500
3957
|
Router._bind();
|
|
3501
3958
|
const defaultView = config.defaultView || "";
|
|
3502
3959
|
if (defaultView && !rootFrame2.view) {
|
|
@@ -3551,7 +4008,7 @@ var Framework = {
|
|
|
3551
4008
|
/**
|
|
3552
4009
|
* Check if object has own property.
|
|
3553
4010
|
*/
|
|
3554
|
-
has,
|
|
4011
|
+
has: hasOwnProperty,
|
|
3555
4012
|
/**
|
|
3556
4013
|
* Get object keys.
|
|
3557
4014
|
*/
|
|
@@ -3611,846 +4068,166 @@ if (typeof window !== "undefined") {
|
|
|
3611
4068
|
window.__lark_Router = Router;
|
|
3612
4069
|
window.__lark_Frame = Frame;
|
|
3613
4070
|
window.__lark_View = View;
|
|
4071
|
+
window.__lark_invalidateViewClass = invalidateViewClass;
|
|
4072
|
+
window.__lark_getViewClassRegistry = getViewClassRegistry;
|
|
4073
|
+
window.__lark_registerViewClass = registerViewClass;
|
|
3614
4074
|
}
|
|
3615
4075
|
|
|
3616
|
-
// src/
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
|
|
3627
|
-
|
|
3628
|
-
var deepClone = (obj) => {
|
|
3629
|
-
if (!obj || !isObject(obj)) return {};
|
|
3630
|
-
const newData = Array.isArray(obj) ? [] : Object.create(Object.getPrototypeOf(obj));
|
|
3631
|
-
for (const key in obj) {
|
|
3632
|
-
if (hasOwnProperty(obj, key)) {
|
|
3633
|
-
const value = obj[key];
|
|
3634
|
-
newData[key] = isObject(value) ? deepClone(value) : value;
|
|
3635
|
-
}
|
|
3636
|
-
}
|
|
3637
|
-
return newData;
|
|
3638
|
-
};
|
|
3639
|
-
var cloneData = (data) => isObject(data) ? deepClone(data) : data;
|
|
3640
|
-
var getDataByKey = (target, key) => {
|
|
3641
|
-
let data;
|
|
3642
|
-
const rec = target;
|
|
3643
|
-
if (key.includes(".")) {
|
|
3644
|
-
key.split(".").forEach((k, index) => {
|
|
3645
|
-
data = index === 0 ? rec?.[k] : data?.[k];
|
|
3646
|
-
});
|
|
3647
|
-
} else {
|
|
3648
|
-
data = rec?.[key];
|
|
3649
|
-
}
|
|
3650
|
-
return data;
|
|
3651
|
-
};
|
|
3652
|
-
var Queue = class {
|
|
3653
|
-
pendingTasks = /* @__PURE__ */ new Set();
|
|
3654
|
-
queue = [];
|
|
3655
|
-
flushTasks() {
|
|
3656
|
-
const { pendingTasks, queue } = this;
|
|
3657
|
-
const flushTickTask = () => {
|
|
3658
|
-
while (queue.length > 0) {
|
|
3659
|
-
const task2 = queue.shift();
|
|
3660
|
-
if (task2) {
|
|
3661
|
-
pendingTasks.delete(task2);
|
|
3662
|
-
runTask(task2);
|
|
3663
|
-
}
|
|
3664
|
-
}
|
|
3665
|
-
};
|
|
3666
|
-
Promise.resolve().then(flushTickTask);
|
|
3667
|
-
}
|
|
3668
|
-
add(tasks) {
|
|
3669
|
-
const isQueueEmpty = this.queue.length === 0;
|
|
3670
|
-
for (const { cb, params } of tasks) {
|
|
3671
|
-
addParams2Callback(cb, params);
|
|
3672
|
-
if (!this.pendingTasks.has(cb)) {
|
|
3673
|
-
this.queue.push(cb);
|
|
3674
|
-
this.pendingTasks.add(cb);
|
|
3675
|
-
}
|
|
4076
|
+
// src/url-state.ts
|
|
4077
|
+
function useUrlState(view, initialState) {
|
|
4078
|
+
const keys2 = initialState ? Object.keys(initialState) : [];
|
|
4079
|
+
if (keys2.length > 0) {
|
|
4080
|
+
view.observeLocation(keys2);
|
|
4081
|
+
}
|
|
4082
|
+
const getState = () => {
|
|
4083
|
+
const loc = Router.parse();
|
|
4084
|
+
const result = { ...initialState || {} };
|
|
4085
|
+
for (const key of keys2) {
|
|
4086
|
+
const val = loc.get(key);
|
|
4087
|
+
if (val) result[key] = val;
|
|
3676
4088
|
}
|
|
3677
|
-
if (isQueueEmpty) this.flushTasks();
|
|
3678
|
-
}
|
|
3679
|
-
delete(tasks) {
|
|
3680
|
-
if (this.pendingTasks.size === 0) return;
|
|
3681
|
-
for (const { cb } of tasks) {
|
|
3682
|
-
if (this.pendingTasks.has(cb)) {
|
|
3683
|
-
this.pendingTasks.delete(cb);
|
|
3684
|
-
const index = this.queue.findIndex((item) => item === cb);
|
|
3685
|
-
if (index !== -1) this.queue.splice(index, 1);
|
|
3686
|
-
}
|
|
3687
|
-
}
|
|
3688
|
-
}
|
|
3689
|
-
clear() {
|
|
3690
|
-
this.queue = [];
|
|
3691
|
-
this.pendingTasks.clear();
|
|
3692
|
-
}
|
|
3693
|
-
};
|
|
3694
|
-
var addParams2Callback = (cb, params) => {
|
|
3695
|
-
if (!cb || !params) return;
|
|
3696
|
-
const cbObj = cb;
|
|
3697
|
-
if (isObject(cb) && isObject(cbObj["params"])) {
|
|
3698
|
-
Object.assign(cbObj["params"], params);
|
|
3699
|
-
} else {
|
|
3700
|
-
cbObj["params"] = params;
|
|
3701
|
-
}
|
|
3702
|
-
};
|
|
3703
|
-
var runTask = (cb) => {
|
|
3704
|
-
const cbObj = cb;
|
|
3705
|
-
const params = cbObj["params"];
|
|
3706
|
-
delete cbObj["params"];
|
|
3707
|
-
try {
|
|
3708
|
-
cb(params);
|
|
3709
|
-
} catch {
|
|
3710
|
-
}
|
|
3711
|
-
};
|
|
3712
|
-
var getDefScheduler = () => new Queue();
|
|
3713
|
-
var run = (tasks, scheduler) => {
|
|
3714
|
-
if (scheduler) {
|
|
3715
|
-
if (isFunction(scheduler)) {
|
|
3716
|
-
for (const { cb, params } of tasks) scheduler(cb, params);
|
|
3717
|
-
} else {
|
|
3718
|
-
scheduler.add(tasks);
|
|
3719
|
-
}
|
|
3720
|
-
} else {
|
|
3721
|
-
for (const { cb, params } of tasks) cb(params);
|
|
3722
|
-
}
|
|
3723
|
-
};
|
|
3724
|
-
var ArrMethods = {};
|
|
3725
|
-
["indexOf", "lastIndexOf", "includes"].forEach((key) => {
|
|
3726
|
-
const rawMethod = Array.prototype[key];
|
|
3727
|
-
ArrMethods[key] = function(...args) {
|
|
3728
|
-
let res = rawMethod.apply(this, args);
|
|
3729
|
-
if (res === -1 || res === false) {
|
|
3730
|
-
res = rawMethod.apply(
|
|
3731
|
-
this,
|
|
3732
|
-
args.map((item) => ProxyCache.get(item) ?? item)
|
|
3733
|
-
);
|
|
3734
|
-
}
|
|
3735
|
-
return res;
|
|
3736
|
-
};
|
|
3737
|
-
});
|
|
3738
|
-
var inArrUpdate = false;
|
|
3739
|
-
["unshift", "shift", "push", "pop", "splice"].forEach((key) => {
|
|
3740
|
-
const rawMethod = Array.prototype[key];
|
|
3741
|
-
ArrMethods[key] = function(...args) {
|
|
3742
|
-
inArrUpdate = true;
|
|
3743
|
-
const result = rawMethod.apply(this, args);
|
|
3744
|
-
inArrUpdate = false;
|
|
3745
4089
|
return result;
|
|
3746
4090
|
};
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
}
|
|
3752
|
-
var defStateConfig = {
|
|
3753
|
-
belong: LARK_GLOBAL,
|
|
3754
|
-
linkKeys: "",
|
|
3755
|
-
shallow: false
|
|
3756
|
-
};
|
|
3757
|
-
var StateConfigMap = /* @__PURE__ */ new WeakMap();
|
|
3758
|
-
var setStateConfig = (target, config2) => {
|
|
3759
|
-
if (target && isObject(config2)) StateConfigMap.set(target, config2);
|
|
3760
|
-
};
|
|
3761
|
-
var getStateConfig = (target, key) => {
|
|
3762
|
-
if (!StateConfigMap.has(target)) {
|
|
3763
|
-
return void 0;
|
|
3764
|
-
}
|
|
3765
|
-
const config2 = StateConfigMap.get(target);
|
|
3766
|
-
return key ? config2?.[key] : config2;
|
|
3767
|
-
};
|
|
3768
|
-
var isState = (target) => isObject(target) && StateConfigMap.has(target);
|
|
3769
|
-
var createLinkKeys = (target, property) => {
|
|
3770
|
-
if (!hasLinkKeys(target)) return property;
|
|
3771
|
-
if (Array.isArray(target)) return getLinkKeys(target) ?? property;
|
|
3772
|
-
return `${getLinkKeys(target)}.${property}`;
|
|
3773
|
-
};
|
|
3774
|
-
var formatLinkKeys = (target, key) => {
|
|
3775
|
-
const originKeysStr = getLinkKeys(target);
|
|
3776
|
-
if (!originKeysStr) return null;
|
|
3777
|
-
const linkKeys = [];
|
|
3778
|
-
const originKeys = originKeysStr.split(".");
|
|
3779
|
-
let pre = "";
|
|
3780
|
-
for (const k of originKeys) {
|
|
3781
|
-
const curr = pre ? `${pre}.${k}` : k;
|
|
3782
|
-
linkKeys.push(curr);
|
|
3783
|
-
pre = curr;
|
|
3784
|
-
}
|
|
3785
|
-
linkKeys.push(`${originKeysStr}.${key}`);
|
|
3786
|
-
return linkKeys;
|
|
3787
|
-
};
|
|
3788
|
-
var getLinkKeys = (target) => getStateConfig(target, "linkKeys");
|
|
3789
|
-
var hasLinkKeys = (target) => !!getLinkKeys(target);
|
|
3790
|
-
var ProxyCache = /* @__PURE__ */ new WeakMap();
|
|
3791
|
-
var keepKey = null;
|
|
3792
|
-
var keep = (key) => {
|
|
3793
|
-
if (keepKey) throw new Error("[lark-store] keepKey is not null");
|
|
3794
|
-
keepKey = key;
|
|
3795
|
-
};
|
|
3796
|
-
var needKeep = (key) => {
|
|
3797
|
-
if (keepKey === key) {
|
|
3798
|
-
keepKey = null;
|
|
3799
|
-
return true;
|
|
3800
|
-
}
|
|
3801
|
-
return false;
|
|
3802
|
-
};
|
|
3803
|
-
var canSetNewVal = (params) => {
|
|
3804
|
-
const { property, newVal, oldVal } = params;
|
|
3805
|
-
if (hasOwnProperty(params.target, property) && newVal === oldVal)
|
|
3806
|
-
return false;
|
|
3807
|
-
return true;
|
|
3808
|
-
};
|
|
3809
|
-
var getNewVal = (params) => {
|
|
3810
|
-
const { target, newVal, property, needKeepVal = false } = params;
|
|
3811
|
-
const config2 = getStateConfig(target);
|
|
3812
|
-
if (!isObject(newVal)) return newVal;
|
|
3813
|
-
if (needKeepArrItem(target, newVal, property)) return newVal;
|
|
3814
|
-
if (config2?.shallow) return newVal;
|
|
3815
|
-
if (needKeepVal) return newVal;
|
|
3816
|
-
const linkKeys = createLinkKeys(target, property);
|
|
3817
|
-
const newState = createState(newVal, {
|
|
3818
|
-
...config2,
|
|
3819
|
-
linkKeys
|
|
3820
|
-
});
|
|
3821
|
-
if (isPromise(newVal)) handlePromise(newVal, target, property);
|
|
3822
|
-
return newState;
|
|
3823
|
-
};
|
|
3824
|
-
var genPayload = (params) => {
|
|
3825
|
-
const { target, property, newVal, oldVal } = params;
|
|
3826
|
-
const config2 = getStateConfig(target) || defStateConfig;
|
|
3827
|
-
return {
|
|
3828
|
-
belong: config2.belong || LARK_GLOBAL,
|
|
3829
|
-
target,
|
|
3830
|
-
keys: formatLinkKeys(target, property) || [property],
|
|
3831
|
-
newVal,
|
|
3832
|
-
oldVal
|
|
3833
|
-
};
|
|
3834
|
-
};
|
|
3835
|
-
var handlePromise = (child, parent, key) => {
|
|
3836
|
-
child.then((res) => {
|
|
3837
|
-
const parentProxy = ProxyCache.get(parent);
|
|
3838
|
-
if (parentProxy) {
|
|
3839
|
-
const oldVal = parentProxy[key];
|
|
3840
|
-
if (ProxyCache.get(child) === oldVal) {
|
|
3841
|
-
parentProxy[key] = res;
|
|
3842
|
-
}
|
|
3843
|
-
}
|
|
3844
|
-
}).catch((err) => {
|
|
3845
|
-
const parentProxy = ProxyCache.get(parent);
|
|
3846
|
-
if (parentProxy) {
|
|
3847
|
-
const oldVal = parentProxy[key];
|
|
3848
|
-
if (ProxyCache.get(child) === oldVal) {
|
|
3849
|
-
parentProxy[key] = err;
|
|
3850
|
-
}
|
|
3851
|
-
}
|
|
3852
|
-
});
|
|
3853
|
-
};
|
|
3854
|
-
var _deleteKey = "_delete";
|
|
3855
|
-
var _markObjKey = "_markObj";
|
|
3856
|
-
var mark2 = (host, key) => {
|
|
3857
|
-
let sign;
|
|
3858
|
-
if (!host[_deleteKey]) {
|
|
3859
|
-
const markHost = host[_markObjKey] || (host[_markObjKey] = {});
|
|
3860
|
-
if (!hasOwnProperty(markHost, key)) {
|
|
3861
|
-
markHost[key] = 0;
|
|
3862
|
-
}
|
|
3863
|
-
sign = ++markHost[key];
|
|
3864
|
-
}
|
|
3865
|
-
return () => {
|
|
3866
|
-
const temp = host[_markObjKey];
|
|
3867
|
-
return !!temp && sign === temp[key];
|
|
4091
|
+
const setState = (patch) => {
|
|
4092
|
+
const current = getState();
|
|
4093
|
+
const resolved = typeof patch === "function" ? patch(current) : patch;
|
|
4094
|
+
Router.to(resolved);
|
|
3868
4095
|
};
|
|
3869
|
-
|
|
3870
|
-
var unmark2 = (host) => {
|
|
3871
|
-
host[_deleteKey] = 1;
|
|
3872
|
-
host[_markObjKey] = 0;
|
|
3873
|
-
};
|
|
3874
|
-
function createState(initialData, config2) {
|
|
3875
|
-
if (!isObject(initialData)) return initialData;
|
|
3876
|
-
const mergedConfig = Object.assign({ ...defStateConfig }, config2);
|
|
3877
|
-
const data = Array.isArray(initialData) ? [] : Object.create(Object.getPrototypeOf(initialData));
|
|
3878
|
-
const handler = {
|
|
3879
|
-
get(target, property, _receiver) {
|
|
3880
|
-
if (Array.isArray(target) && property in ArrMethods) {
|
|
3881
|
-
return ArrMethods[property];
|
|
3882
|
-
}
|
|
3883
|
-
return Reflect.get(target, property);
|
|
3884
|
-
},
|
|
3885
|
-
set(target, property, newVal, receiver) {
|
|
3886
|
-
const strProp = property;
|
|
3887
|
-
const oldVal = Reflect.get(target, property);
|
|
3888
|
-
const preventTrigger = isLazySet(strProp);
|
|
3889
|
-
const needKeepVal = needKeep(strProp);
|
|
3890
|
-
const canSet = canSetNewVal({
|
|
3891
|
-
target,
|
|
3892
|
-
property: strProp,
|
|
3893
|
-
newVal,
|
|
3894
|
-
oldVal
|
|
3895
|
-
});
|
|
3896
|
-
if (!canSet) return true;
|
|
3897
|
-
const proxyTarget = receiver || state;
|
|
3898
|
-
newVal = getNewVal({
|
|
3899
|
-
target: proxyTarget,
|
|
3900
|
-
property: strProp,
|
|
3901
|
-
newVal,
|
|
3902
|
-
needKeepVal
|
|
3903
|
-
});
|
|
3904
|
-
Reflect.set(target, property, newVal, receiver);
|
|
3905
|
-
if (preventTrigger) return true;
|
|
3906
|
-
const payload = genPayload({
|
|
3907
|
-
target: proxyTarget,
|
|
3908
|
-
property: strProp,
|
|
3909
|
-
newVal,
|
|
3910
|
-
oldVal
|
|
3911
|
-
});
|
|
3912
|
-
trigger(payload);
|
|
3913
|
-
return true;
|
|
3914
|
-
},
|
|
3915
|
-
deleteProperty(target, property) {
|
|
3916
|
-
const strProp = property;
|
|
3917
|
-
if (!hasOwnProperty(target, strProp)) return true;
|
|
3918
|
-
const oldVal = Reflect.get(target, property);
|
|
3919
|
-
Reflect.deleteProperty(target, property);
|
|
3920
|
-
const payload = genPayload({
|
|
3921
|
-
target: state,
|
|
3922
|
-
property: strProp,
|
|
3923
|
-
newVal: null,
|
|
3924
|
-
oldVal
|
|
3925
|
-
});
|
|
3926
|
-
trigger(payload);
|
|
3927
|
-
return true;
|
|
3928
|
-
}
|
|
3929
|
-
};
|
|
3930
|
-
const state = new Proxy(data, handler);
|
|
3931
|
-
ProxyCache.set(initialData, state);
|
|
3932
|
-
setStateConfig(state, mergedConfig);
|
|
3933
|
-
lazySet(state, initialData);
|
|
3934
|
-
return state;
|
|
3935
|
-
}
|
|
3936
|
-
var curLazySetKey = null;
|
|
3937
|
-
function lazySet(target, data) {
|
|
3938
|
-
if (isObject(data)) {
|
|
3939
|
-
Reflect.ownKeys(data).forEach((key) => {
|
|
3940
|
-
const strKey = key;
|
|
3941
|
-
if (curLazySetKey) throw new Error("[lark-store] lazy set key conflict");
|
|
3942
|
-
curLazySetKey = strKey;
|
|
3943
|
-
target[strKey] = data[strKey];
|
|
3944
|
-
});
|
|
3945
|
-
}
|
|
4096
|
+
return [getState(), setState];
|
|
3946
4097
|
}
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
return false;
|
|
4098
|
+
|
|
4099
|
+
// src/store.ts
|
|
4100
|
+
var COMPUTED_BRAND = /* @__PURE__ */ Symbol("lark-store-computed");
|
|
4101
|
+
function isComputedMarker(val) {
|
|
4102
|
+
return val !== null && typeof val === "object" && val[COMPUTED_BRAND] === true;
|
|
3953
4103
|
}
|
|
3954
|
-
function
|
|
3955
|
-
|
|
3956
|
-
throw new Error("[lark-store] shallowSet only supports state objects");
|
|
3957
|
-
if (!isObject(data)) return target[key] = data;
|
|
3958
|
-
keep(key);
|
|
3959
|
-
const config2 = getStateConfig(target);
|
|
3960
|
-
const linkKeys = createLinkKeys(target, key);
|
|
3961
|
-
target[key] = createState(data, {
|
|
3962
|
-
...config2,
|
|
3963
|
-
linkKeys,
|
|
3964
|
-
shallow: true
|
|
3965
|
-
});
|
|
4104
|
+
function computed(deps, fn) {
|
|
4105
|
+
return { [COMPUTED_BRAND]: true, deps, fn };
|
|
3966
4106
|
}
|
|
3967
|
-
var
|
|
3968
|
-
function
|
|
3969
|
-
const
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
|
|
3985
|
-
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
for (const key of keys2) {
|
|
3989
|
-
const callbacks = deps.get(key);
|
|
3990
|
-
if (callbacks) {
|
|
3991
|
-
for (const cb of callbacks) {
|
|
3992
|
-
tasks.add({ cb, params: { [key]: true } });
|
|
3993
|
-
}
|
|
3994
|
-
}
|
|
3995
|
-
}
|
|
3996
|
-
if (tasks.size === 0) return;
|
|
3997
|
-
const scheduler = store?.scheduler;
|
|
3998
|
-
run(Array.from(tasks), scheduler);
|
|
3999
|
-
}
|
|
4000
|
-
function clear(payload) {
|
|
4001
|
-
if (!payload) {
|
|
4002
|
-
GlobalDeps.clear();
|
|
4003
|
-
return;
|
|
4004
|
-
}
|
|
4005
|
-
const { belong, clearList } = payload;
|
|
4006
|
-
const deps = GlobalDeps.get(belong);
|
|
4007
|
-
if (!deps) return;
|
|
4008
|
-
const store = getStore(belong);
|
|
4009
|
-
const scheduler = store?.scheduler;
|
|
4010
|
-
if (clearList) {
|
|
4011
|
-
for (const { key, cb } of clearList) {
|
|
4012
|
-
const callbacks = deps.get(key);
|
|
4013
|
-
if (callbacks) {
|
|
4014
|
-
if (!cb) {
|
|
4015
|
-
deps.delete(key);
|
|
4016
|
-
} else if (callbacks.has(cb)) {
|
|
4017
|
-
callbacks.delete(cb);
|
|
4018
|
-
if (scheduler && !isFunction(scheduler)) {
|
|
4019
|
-
scheduler.delete([{ cb }]);
|
|
4020
|
-
}
|
|
4021
|
-
if (callbacks.size === 0) deps.delete(key);
|
|
4107
|
+
var storeRegistry = /* @__PURE__ */ new Map();
|
|
4108
|
+
function create(name, creator) {
|
|
4109
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
4110
|
+
const computedDefs = /* @__PURE__ */ new Map();
|
|
4111
|
+
const computedKeys = /* @__PURE__ */ new Set();
|
|
4112
|
+
const actionKeys = /* @__PURE__ */ new Set();
|
|
4113
|
+
let state;
|
|
4114
|
+
let destroyed = false;
|
|
4115
|
+
const getState = () => state;
|
|
4116
|
+
const setState = (partial) => {
|
|
4117
|
+
if (destroyed) return;
|
|
4118
|
+
const prevState = state;
|
|
4119
|
+
const resolved = typeof partial === "function" ? partial(prevState) : partial;
|
|
4120
|
+
const nextState = { ...prevState };
|
|
4121
|
+
let changed = false;
|
|
4122
|
+
for (const key in resolved) {
|
|
4123
|
+
if (Object.prototype.hasOwnProperty.call(resolved, key) && !computedKeys.has(key) && !actionKeys.has(key)) {
|
|
4124
|
+
const newVal = resolved[key];
|
|
4125
|
+
if (!Object.is(prevState[key], newVal)) {
|
|
4126
|
+
nextState[key] = newVal;
|
|
4127
|
+
changed = true;
|
|
4022
4128
|
}
|
|
4023
4129
|
}
|
|
4024
4130
|
}
|
|
4025
|
-
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
}
|
|
4031
|
-
}
|
|
4032
|
-
}
|
|
4033
|
-
var _storeName = /* @__PURE__ */ Symbol("store-name");
|
|
4034
|
-
var _storeStatus = /* @__PURE__ */ Symbol("store-status");
|
|
4035
|
-
var _storeScheduler = /* @__PURE__ */ Symbol("store-scheduler");
|
|
4036
|
-
var _storeCreate = /* @__PURE__ */ Symbol("fn:store-create");
|
|
4037
|
-
var _storeBoot = /* @__PURE__ */ Symbol("fn:store-boot");
|
|
4038
|
-
var _storeDestroy = /* @__PURE__ */ Symbol("fn:store-destroy");
|
|
4039
|
-
var _innerStore = /* @__PURE__ */ Symbol("inner-store");
|
|
4040
|
-
var _outerStore = /* @__PURE__ */ Symbol("outer-store");
|
|
4041
|
-
var _originState = /* @__PURE__ */ Symbol("origin-state");
|
|
4042
|
-
var _stateKeys = /* @__PURE__ */ Symbol("state-keys");
|
|
4043
|
-
var _storeState = /* @__PURE__ */ Symbol("store-state");
|
|
4044
|
-
var _storeDefScheduler = /* @__PURE__ */ Symbol("store-def-scheduler");
|
|
4045
|
-
var _storeProxy = /* @__PURE__ */ Symbol("fn:store-proxy");
|
|
4046
|
-
var BaseStore = class {
|
|
4047
|
-
[_storeStatus] = 0 /* BEFORE_CREATE */;
|
|
4048
|
-
[_storeDefScheduler] = getDefScheduler;
|
|
4049
|
-
[_storeBoot]() {
|
|
4050
|
-
this[_storeStatus] = 2 /* ACTIVE */;
|
|
4051
|
-
return this[_storeProxy](true);
|
|
4052
|
-
}
|
|
4053
|
-
[_storeDestroy]() {
|
|
4054
|
-
clear({ belong: this[_storeName] });
|
|
4055
|
-
this[_storeState] = createState(this[_originState], {
|
|
4056
|
-
belong: this[_storeName]
|
|
4057
|
-
});
|
|
4058
|
-
this[_storeStatus] = 3 /* DESTROYED */;
|
|
4059
|
-
}
|
|
4060
|
-
/**
|
|
4061
|
-
*
|
|
4062
|
-
* @param body - The object returned by the creator function
|
|
4063
|
-
* @param excludeFns - Function keys to exclude from handlers (e.g. ['observe'])
|
|
4064
|
-
*/
|
|
4065
|
-
[_storeCreate](body, excludeFns = ["observe"]) {
|
|
4066
|
-
this[_storeStatus] = 1 /* CREATED */;
|
|
4067
|
-
if (isObject(body)) {
|
|
4068
|
-
const state = {};
|
|
4069
|
-
const handlers = {};
|
|
4070
|
-
Reflect.ownKeys(body).forEach((key) => {
|
|
4071
|
-
const strKey = key;
|
|
4072
|
-
const val = body[strKey];
|
|
4073
|
-
if (isFunction(val)) {
|
|
4074
|
-
if (!excludeFns.includes(strKey)) handlers[strKey] = val;
|
|
4075
|
-
} else {
|
|
4076
|
-
state[strKey] = val;
|
|
4077
|
-
}
|
|
4078
|
-
});
|
|
4079
|
-
Object.assign(this, handlers);
|
|
4080
|
-
this[_originState] = cloneData(state);
|
|
4081
|
-
this[_stateKeys] = Object.keys(state);
|
|
4082
|
-
this[_storeState] = createState(state, { belong: this[_storeName] });
|
|
4131
|
+
if (!changed) return;
|
|
4132
|
+
state = nextState;
|
|
4133
|
+
recomputeIfNeeded(prevState);
|
|
4134
|
+
for (const listener of listeners) {
|
|
4135
|
+
listener(state, prevState);
|
|
4083
4136
|
}
|
|
4084
|
-
}
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
return this[_storeStatus];
|
|
4095
|
-
}
|
|
4096
|
-
get storeName() {
|
|
4097
|
-
return this[_storeName];
|
|
4098
|
-
}
|
|
4099
|
-
get scheduler() {
|
|
4100
|
-
return this[_storeScheduler];
|
|
4101
|
-
}
|
|
4102
|
-
[_storeProxy](toOut = false) {
|
|
4103
|
-
const self = this;
|
|
4104
|
-
return new Proxy(self, {
|
|
4105
|
-
get(target, property) {
|
|
4106
|
-
if (self[_stateKeys].includes(property)) {
|
|
4107
|
-
const val = self[_storeState][property];
|
|
4108
|
-
return toOut ? cloneData(val) : val;
|
|
4109
|
-
}
|
|
4110
|
-
return Reflect.get(target, property);
|
|
4111
|
-
},
|
|
4112
|
-
set(_target, property, val) {
|
|
4113
|
-
if (toOut) return true;
|
|
4114
|
-
if (self[_stateKeys].includes(property)) {
|
|
4115
|
-
self[_storeState][property] = val;
|
|
4116
|
-
}
|
|
4117
|
-
return true;
|
|
4118
|
-
},
|
|
4119
|
-
has(target, property) {
|
|
4120
|
-
return Reflect.has(target, property) || self[_stateKeys].includes(property);
|
|
4137
|
+
};
|
|
4138
|
+
const recomputeIfNeeded = (prevState) => {
|
|
4139
|
+
if (computedDefs.size === 0) return;
|
|
4140
|
+
const changedKeys2 = /* @__PURE__ */ new Set();
|
|
4141
|
+
for (const key of Object.keys(state)) {
|
|
4142
|
+
if (!Object.is(
|
|
4143
|
+
state[key],
|
|
4144
|
+
prevState[key]
|
|
4145
|
+
)) {
|
|
4146
|
+
changedKeys2.add(key);
|
|
4121
4147
|
}
|
|
4122
|
-
});
|
|
4123
|
-
}
|
|
4124
|
-
};
|
|
4125
|
-
var LarkUtils = {
|
|
4126
|
-
isLarkView(instance) {
|
|
4127
|
-
return isObject(instance) && !!instance.updater;
|
|
4128
|
-
},
|
|
4129
|
-
getRender(view) {
|
|
4130
|
-
return view.updater.digest.bind(view.updater);
|
|
4131
|
-
},
|
|
4132
|
-
getDataSetter(view) {
|
|
4133
|
-
return view.updater.set.bind(view.updater);
|
|
4134
|
-
},
|
|
4135
|
-
onDestroy(view, cb) {
|
|
4136
|
-
view.on("destroy", cb);
|
|
4137
|
-
}
|
|
4138
|
-
};
|
|
4139
|
-
var getLarkAdapter = (storeName) => ({
|
|
4140
|
-
Store: LarkStore,
|
|
4141
|
-
useStore: ((view) => {
|
|
4142
|
-
const store = getStore(storeName);
|
|
4143
|
-
return store[_storeBoot](view);
|
|
4144
|
-
})
|
|
4145
|
-
});
|
|
4146
|
-
var innerObserveFlags = /* @__PURE__ */ Symbol("store-inner-observe-flags");
|
|
4147
|
-
var boundViews = /* @__PURE__ */ Symbol("bound-views");
|
|
4148
|
-
var LarkStore = class extends BaseStore {
|
|
4149
|
-
[boundViews] = /* @__PURE__ */ new Set();
|
|
4150
|
-
[innerObserveFlags] = /* @__PURE__ */ new Set();
|
|
4151
|
-
[_storeBoot](view) {
|
|
4152
|
-
if (view && LarkUtils.isLarkView(view) && !this[boundViews].has(view)) {
|
|
4153
|
-
this[boundViews].add(view);
|
|
4154
|
-
LarkUtils.onDestroy(view, () => {
|
|
4155
|
-
this[boundViews].delete(view);
|
|
4156
|
-
});
|
|
4157
4148
|
}
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
observe(view, keys2, defCallback) {
|
|
4166
|
-
if (this[_storeStatus] !== 2 /* ACTIVE */) return noop;
|
|
4167
|
-
let observeKeys = keys2;
|
|
4168
|
-
const _view = view;
|
|
4169
|
-
const renderFn = _view ? LarkUtils.getRender(_view) : noop;
|
|
4170
|
-
const dateSetterFn = _view ? LarkUtils.getDataSetter(_view) : noop;
|
|
4171
|
-
const isInnerObserve = !view;
|
|
4172
|
-
const innerFlags = /* @__PURE__ */ new Set();
|
|
4173
|
-
const storeInnerObserveFlags = this[innerObserveFlags];
|
|
4174
|
-
if (isFunction(keys2)) {
|
|
4175
|
-
const res = keys2();
|
|
4176
|
-
if (Array.isArray(res)) observeKeys = res;
|
|
4177
|
-
}
|
|
4178
|
-
const defSetter = (immediate, key, alias, transform) => () => {
|
|
4179
|
-
const stateVal = getDataByKey(this, key);
|
|
4180
|
-
let data = { [alias || key]: stateVal };
|
|
4181
|
-
if (transform && isFunction(transform)) {
|
|
4182
|
-
const newData = transform(stateVal);
|
|
4183
|
-
if (isObject(newData)) data = newData;
|
|
4184
|
-
}
|
|
4185
|
-
if (immediate) dateSetterFn(data);
|
|
4186
|
-
else renderFn(data);
|
|
4187
|
-
};
|
|
4188
|
-
const getList = (immediate = false) => {
|
|
4189
|
-
const list = [];
|
|
4190
|
-
for (const item of observeKeys) {
|
|
4191
|
-
if (!item) continue;
|
|
4192
|
-
const payload = typeof item === "string" ? { key: item } : item;
|
|
4193
|
-
const { cb: cbDefault = defCallback, key } = payload;
|
|
4194
|
-
let cb = cbDefault;
|
|
4195
|
-
const { alias, lazy = true, transform } = payload;
|
|
4196
|
-
if (!key) continue;
|
|
4197
|
-
const c1 = !immediate;
|
|
4198
|
-
const c2 = !cb && !!_view;
|
|
4199
|
-
const c3 = !!cb && String(lazy) === "false";
|
|
4200
|
-
if (!(c1 || c2 || c3)) continue;
|
|
4201
|
-
if (isInnerObserve && cb) {
|
|
4202
|
-
const flag = `storeInner_${key}_${observeKeys.join("-")}_${cb.toString()}`;
|
|
4203
|
-
if (!storeInnerObserveFlags.has(flag)) {
|
|
4204
|
-
storeInnerObserveFlags.add(flag);
|
|
4205
|
-
innerFlags.add(flag);
|
|
4206
|
-
}
|
|
4149
|
+
let recomputed = false;
|
|
4150
|
+
for (const [key, def] of computedDefs) {
|
|
4151
|
+
if (def.deps.some((dep) => changedKeys2.has(dep))) {
|
|
4152
|
+
const newVal = def.fn();
|
|
4153
|
+
if (!Object.is(state[key], newVal)) {
|
|
4154
|
+
state[key] = newVal;
|
|
4155
|
+
recomputed = true;
|
|
4207
4156
|
}
|
|
4208
|
-
if (c2) cb = defSetter(immediate, key, alias, transform);
|
|
4209
|
-
if (cb) list.push({ key, cb });
|
|
4210
4157
|
}
|
|
4211
|
-
return list;
|
|
4212
|
-
};
|
|
4213
|
-
const trackList = getList();
|
|
4214
|
-
track({ belong: this[_storeName], trackList });
|
|
4215
|
-
if (_view) {
|
|
4216
|
-
LarkUtils.onDestroy(
|
|
4217
|
-
_view,
|
|
4218
|
-
() => clear({ belong: this[_storeName], clearList: trackList })
|
|
4219
|
-
);
|
|
4220
4158
|
}
|
|
4221
|
-
if (
|
|
4159
|
+
if (recomputed) {
|
|
4160
|
+
}
|
|
4161
|
+
};
|
|
4162
|
+
const subscribe = (listener) => {
|
|
4163
|
+
listeners.add(listener);
|
|
4222
4164
|
return () => {
|
|
4223
|
-
|
|
4224
|
-
innerFlags.forEach((flag) => storeInnerObserveFlags.delete(flag));
|
|
4165
|
+
listeners.delete(listener);
|
|
4225
4166
|
};
|
|
4226
|
-
}
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
}
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
} : config2;
|
|
4246
|
-
super(name, effectiveConfig);
|
|
4247
|
-
}
|
|
4248
|
-
[_storeCreate](body) {
|
|
4249
|
-
super[_storeCreate](body);
|
|
4250
|
-
this[observeSym](() => {
|
|
4251
|
-
this.stateChangeCount += 1;
|
|
4252
|
-
});
|
|
4253
|
-
}
|
|
4254
|
-
isStateChanged() {
|
|
4255
|
-
const currCount = this.stateChangeCount;
|
|
4256
|
-
const changed = this.lastCount !== currCount;
|
|
4257
|
-
this.lastCount = currCount;
|
|
4258
|
-
return changed;
|
|
4259
|
-
}
|
|
4260
|
-
[getLastState](handlers) {
|
|
4261
|
-
if (this.isStateChanged() || !this.lastState) {
|
|
4262
|
-
const state = this[_storeState];
|
|
4263
|
-
const immutableState = freezeData(state);
|
|
4264
|
-
this.lastState = Object.assign({}, handlers, immutableState);
|
|
4265
|
-
}
|
|
4266
|
-
return this.lastState;
|
|
4267
|
-
}
|
|
4268
|
-
[observeSym](cb) {
|
|
4269
|
-
const tasks = this[_stateKeys].map((key) => ({ key, cb }));
|
|
4270
|
-
track({ belong: this[_storeName], trackList: tasks });
|
|
4271
|
-
return () => clear({ belong: this[_storeName], clearList: tasks });
|
|
4272
|
-
}
|
|
4273
|
-
};
|
|
4274
|
-
var freezeData = (target) => {
|
|
4275
|
-
const data = {};
|
|
4276
|
-
const keys2 = Object.keys(target);
|
|
4277
|
-
for (const key of keys2) {
|
|
4278
|
-
const value = target[key];
|
|
4279
|
-
if (Array.isArray(value)) {
|
|
4280
|
-
data[key] = value.map(
|
|
4281
|
-
(item) => isObject(item) ? freezeData(item) : item
|
|
4282
|
-
);
|
|
4283
|
-
} else if (isObject(value)) {
|
|
4284
|
-
data[key] = freezeData(value);
|
|
4167
|
+
};
|
|
4168
|
+
const destroy = () => {
|
|
4169
|
+
destroyed = true;
|
|
4170
|
+
listeners.clear();
|
|
4171
|
+
storeRegistry.delete(name);
|
|
4172
|
+
};
|
|
4173
|
+
const api = { getState, setState, subscribe, destroy };
|
|
4174
|
+
const body = creator(setState, getState);
|
|
4175
|
+
const initialState = {};
|
|
4176
|
+
const actions = {};
|
|
4177
|
+
for (const key of Object.keys(body)) {
|
|
4178
|
+
const val = body[key];
|
|
4179
|
+
if (isComputedMarker(val)) {
|
|
4180
|
+
computedDefs.set(key, val);
|
|
4181
|
+
computedKeys.add(key);
|
|
4182
|
+
initialState[key] = void 0;
|
|
4183
|
+
} else if (typeof val === "function") {
|
|
4184
|
+
actions[key] = val;
|
|
4185
|
+
actionKeys.add(key);
|
|
4285
4186
|
} else {
|
|
4286
|
-
|
|
4187
|
+
initialState[key] = val;
|
|
4287
4188
|
}
|
|
4288
4189
|
}
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
Store: NodeStore,
|
|
4293
|
-
useStore: (() => {
|
|
4294
|
-
const store = getStore(storeName);
|
|
4295
|
-
return store[_storeBoot]();
|
|
4296
|
-
})
|
|
4297
|
-
});
|
|
4298
|
-
var NodeStore = class extends BaseStore {
|
|
4299
|
-
observe(key, callback, immediate = true) {
|
|
4300
|
-
const tasks = [{ key, cb: callback }];
|
|
4301
|
-
track({ belong: this[_storeName], trackList: tasks });
|
|
4302
|
-
if (immediate) run(tasks);
|
|
4303
|
-
return () => clear({ belong: this[_storeName], clearList: tasks });
|
|
4304
|
-
}
|
|
4305
|
-
};
|
|
4306
|
-
var getAdapter = (platform, storeName) => {
|
|
4307
|
-
switch (platform) {
|
|
4308
|
-
case "react" /* React */:
|
|
4309
|
-
return getReactAdapter(storeName);
|
|
4310
|
-
case "node" /* Node */:
|
|
4311
|
-
return getNodeAdapter(storeName);
|
|
4312
|
-
case "lark" /* Lark */:
|
|
4313
|
-
default:
|
|
4314
|
-
return getLarkAdapter(storeName);
|
|
4315
|
-
}
|
|
4316
|
-
};
|
|
4317
|
-
var getPlatform = (comp) => {
|
|
4318
|
-
if (LarkUtils.isLarkView(comp)) return "lark" /* Lark */;
|
|
4319
|
-
return void 0;
|
|
4320
|
-
};
|
|
4321
|
-
var extendApis = { lazySet, shallowSet };
|
|
4322
|
-
var StoreCache = /* @__PURE__ */ new Map();
|
|
4323
|
-
function defineStore(name, creator, config2) {
|
|
4324
|
-
if (StoreCache.has(name)) {
|
|
4325
|
-
name = name + "_copy";
|
|
4326
|
-
}
|
|
4327
|
-
const { platform = "lark" /* Lark */ } = config2 || {};
|
|
4328
|
-
const adapter = getAdapter(platform, name);
|
|
4329
|
-
const StoreClass = adapter.Store;
|
|
4330
|
-
const useStore = adapter.useStore;
|
|
4331
|
-
const store = new StoreClass(name, config2);
|
|
4332
|
-
store[_storeCreate](
|
|
4333
|
-
creator(store[_innerStore](), extendApis)
|
|
4334
|
-
);
|
|
4335
|
-
Object.defineProperties(useStore, {
|
|
4336
|
-
$storeName: { value: name, configurable: true },
|
|
4337
|
-
$destroyFn: { value: () => store[_storeDestroy](), configurable: true }
|
|
4338
|
-
});
|
|
4339
|
-
if (!StoreCache.has(name)) {
|
|
4340
|
-
StoreCache.set(name, { store, creator, config: config2, useStore });
|
|
4341
|
-
}
|
|
4342
|
-
return useStore;
|
|
4343
|
-
}
|
|
4344
|
-
function getStore(name) {
|
|
4345
|
-
if (name && StoreCache.has(name)) {
|
|
4346
|
-
const entry = StoreCache.get(name);
|
|
4347
|
-
return entry ? entry.store : void 0;
|
|
4348
|
-
}
|
|
4349
|
-
return void 0;
|
|
4350
|
-
}
|
|
4351
|
-
function delStore(name) {
|
|
4352
|
-
if (name && StoreCache.has(name)) StoreCache.delete(name);
|
|
4353
|
-
}
|
|
4354
|
-
function getUseStore(name) {
|
|
4355
|
-
if (name && StoreCache.has(name)) {
|
|
4356
|
-
const entry = StoreCache.get(name);
|
|
4357
|
-
return entry ? entry.useStore : void 0;
|
|
4190
|
+
state = { ...initialState, ...actions };
|
|
4191
|
+
for (const [key, def] of computedDefs) {
|
|
4192
|
+
state[key] = def.fn();
|
|
4358
4193
|
}
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
function cloneStore(name, useStore, config2) {
|
|
4362
|
-
const oldStoreName = useStore["$storeName"];
|
|
4363
|
-
const cached = StoreCache.get(oldStoreName);
|
|
4364
|
-
const oldStoreCreator = cached?.creator;
|
|
4365
|
-
const oldConfig = cached?.config || {};
|
|
4366
|
-
if (!name || !oldStoreCreator) return;
|
|
4367
|
-
const mergedConfig = { ...oldConfig, ...config2 || {} };
|
|
4368
|
-
return defineStore(
|
|
4369
|
-
name,
|
|
4370
|
-
oldStoreCreator,
|
|
4371
|
-
mergedConfig
|
|
4372
|
-
);
|
|
4194
|
+
storeRegistry.set(name, api);
|
|
4195
|
+
return api;
|
|
4373
4196
|
}
|
|
4374
|
-
function
|
|
4375
|
-
if (
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
return false;
|
|
4380
|
-
}
|
|
4381
|
-
var cellCount = 0;
|
|
4382
|
-
function cell(data) {
|
|
4383
|
-
return createState(data, {
|
|
4384
|
-
belong: LARK_GLOBAL,
|
|
4385
|
-
linkKeys: `${LARK_GLOBAL}_${cellCount++}`
|
|
4386
|
-
});
|
|
4387
|
-
}
|
|
4388
|
-
function observeCell(state, cb, immediate = true) {
|
|
4389
|
-
const linkKeys = getLinkKeys(state);
|
|
4390
|
-
if (!linkKeys)
|
|
4391
|
-
return () => {
|
|
4392
|
-
};
|
|
4393
|
-
const keys2 = linkKeys.split(".");
|
|
4394
|
-
const key = keys2[keys2.length - 1];
|
|
4395
|
-
const list = [{ key, cb }];
|
|
4396
|
-
track({ belong: LARK_GLOBAL, trackList: list });
|
|
4397
|
-
if (immediate) cb();
|
|
4398
|
-
return () => clear({ belong: LARK_GLOBAL, clearList: list });
|
|
4197
|
+
function isLarkView(instance) {
|
|
4198
|
+
if (!instance || typeof instance !== "object") return false;
|
|
4199
|
+
const obj = instance;
|
|
4200
|
+
const updater = obj["updater"];
|
|
4201
|
+
return updater !== null && typeof updater === "object" && typeof updater["set"] === "function" && typeof updater["digest"] === "function";
|
|
4399
4202
|
}
|
|
4400
|
-
function
|
|
4401
|
-
|
|
4402
|
-
const flagSym = `lark-comp-${storeName}`;
|
|
4403
|
-
const map = /* @__PURE__ */ new Map();
|
|
4404
|
-
let rootViewPath;
|
|
4405
|
-
const getFlag = (viewContext) => {
|
|
4406
|
-
const owner = viewContext["owner"];
|
|
4407
|
-
const viewPath = owner?.["path"] || "";
|
|
4408
|
-
const viewId = owner?.["id"] || "";
|
|
4409
|
-
let flag;
|
|
4410
|
-
if (viewPath === rootViewPath) {
|
|
4411
|
-
flag = `${flagSym}-${viewId}`;
|
|
4412
|
-
} else {
|
|
4413
|
-
flag = owner?.["viewInitParams"]?.[flagSym];
|
|
4414
|
-
}
|
|
4415
|
-
if (owner && isFunction(owner["mountFrame"])) {
|
|
4416
|
-
const rawMountFrame = owner["mountFrame"];
|
|
4417
|
-
owner["mountFrame"] = (vfId, viewPath2, viewInitParams = {}) => rawMountFrame.call(
|
|
4418
|
-
owner,
|
|
4419
|
-
vfId,
|
|
4420
|
-
viewPath2,
|
|
4421
|
-
Object.assign(viewInitParams, { [flagSym]: flag })
|
|
4422
|
-
);
|
|
4423
|
-
}
|
|
4424
|
-
return flag;
|
|
4203
|
+
function bindStore(view, store, selector) {
|
|
4204
|
+
if (!isLarkView(view)) return () => {
|
|
4425
4205
|
};
|
|
4426
|
-
const
|
|
4427
|
-
if (
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
)
|
|
4431
|
-
|
|
4432
|
-
const flag = viewCtx[flagSym];
|
|
4433
|
-
if (map.has(flag)) return map.get(flag);
|
|
4434
|
-
const newFn = cloneStore(flag, useStore);
|
|
4435
|
-
map.set(flag, newFn);
|
|
4436
|
-
return useFn(view);
|
|
4437
|
-
});
|
|
4438
|
-
const mixinObj = {
|
|
4439
|
-
make() {
|
|
4440
|
-
if (!rootViewPath) {
|
|
4441
|
-
const owner = this["owner"];
|
|
4442
|
-
rootViewPath = owner?.["path"] || "";
|
|
4206
|
+
const extract = (s) => {
|
|
4207
|
+
if (selector) return selector(s);
|
|
4208
|
+
const result = {};
|
|
4209
|
+
for (const key in s) {
|
|
4210
|
+
if (Object.prototype.hasOwnProperty.call(s, key) && typeof s[key] !== "function") {
|
|
4211
|
+
result[key] = s[key];
|
|
4443
4212
|
}
|
|
4444
|
-
this[flagSym] = getFlag(this);
|
|
4445
4213
|
}
|
|
4214
|
+
return result;
|
|
4446
4215
|
};
|
|
4447
|
-
|
|
4216
|
+
view.updater.set(extract(store.getState()));
|
|
4217
|
+
view.updater.digest();
|
|
4218
|
+
const off = store.subscribe((state) => {
|
|
4219
|
+
view.updater.set(extract(state));
|
|
4220
|
+
view.updater.digest();
|
|
4221
|
+
});
|
|
4222
|
+
view.on("destroy", off);
|
|
4223
|
+
return off;
|
|
4448
4224
|
}
|
|
4225
|
+
var defineStore = create;
|
|
4449
4226
|
|
|
4450
4227
|
// src/compiler.ts
|
|
4451
4228
|
import { parse as babelParse } from "@babel/parser";
|
|
4452
|
-
var SPLITTER2 =
|
|
4453
|
-
var VIEW_ID_PLACEHOLDER =
|
|
4229
|
+
var SPLITTER2 = String.fromCharCode(30);
|
|
4230
|
+
var VIEW_ID_PLACEHOLDER = String.fromCharCode(31);
|
|
4454
4231
|
function jsObjectToUrlParams(paramsStr) {
|
|
4455
4232
|
const trimmed = paramsStr.trim();
|
|
4456
4233
|
if (!/^[{[]/.test(trimmed) && /=/.test(trimmed)) {
|
|
@@ -4510,7 +4287,7 @@ function addLineMarkers(source) {
|
|
|
4510
4287
|
if (parts.length > 1) {
|
|
4511
4288
|
const reconstructed = parts.map((part, i) => {
|
|
4512
4289
|
if (i === 0) return part;
|
|
4513
|
-
return openTag + SPLITTER2 + ++lineNo;
|
|
4290
|
+
return openTag + SPLITTER2 + ++lineNo + part;
|
|
4514
4291
|
}).join("");
|
|
4515
4292
|
result.push(reconstructed);
|
|
4516
4293
|
} else {
|
|
@@ -4646,7 +4423,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
|
|
|
4646
4423
|
return `${debugPrefix}<%for(${forExpr}){%>`;
|
|
4647
4424
|
}
|
|
4648
4425
|
const tokens = code.split(/\s+/);
|
|
4649
|
-
const keyword = tokens.shift();
|
|
4426
|
+
const keyword = tokens.shift() ?? "";
|
|
4650
4427
|
switch (keyword) {
|
|
4651
4428
|
case "if": {
|
|
4652
4429
|
blockStack.push({ ctrl: "if", line: lineNo });
|
|
@@ -4870,13 +4647,9 @@ function compileToFunction(source, debug, file) {
|
|
|
4870
4647
|
}
|
|
4871
4648
|
const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
|
|
4872
4649
|
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,'\\\\$&')}`;
|
|
4650
|
+
void hasAtRule;
|
|
4877
4651
|
const refFallback = "if(!$refAlt)$refAlt=$data;";
|
|
4878
|
-
const
|
|
4879
|
-
const fullSource = `${fns}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
|
|
4652
|
+
const fullSource = `${refFallback}let $splitter='\\x1e',$tmp,$out=''{{VARS}};${funcSource}return $out`;
|
|
4880
4653
|
return `($data,$viewId,$refAlt,$encHtml,$strSafe,$encUri,$refFn,$encQuote)=>{${fullSource}}`;
|
|
4881
4654
|
}
|
|
4882
4655
|
function compileTemplate(source, options = {}) {
|
|
@@ -4888,15 +4661,12 @@ function compileTemplate(source, options = {}) {
|
|
|
4888
4661
|
const funcBody = compileToFunction(finalSource, debug, file);
|
|
4889
4662
|
const varDeclarations = globalVars.map((key) => `,${key}=$data.${key}`).join("");
|
|
4890
4663
|
const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
|
|
4891
|
-
return `
|
|
4664
|
+
return `import { encHtml as __larkEncHtml, strSafe as __larkStrSafe, encUri as __larkEncUri, encQuote as __larkEncQuote, refFn as __larkRefFn } from "@lark.js/mvc/runtime";
|
|
4665
|
+
export default function(data, viewId, refData) {
|
|
4892
4666
|
let $data = data || {},
|
|
4893
|
-
$viewId =
|
|
4667
|
+
$viewId = viewId || '';
|
|
4894
4668
|
return (${funcWithVars})($data, $viewId, refData,
|
|
4895
|
-
|
|
4896
|
-
/* $strSafe */ v => String(v == null ? '' : v),
|
|
4897
|
-
/* $encUri */ null,
|
|
4898
|
-
/* $refFn */ null,
|
|
4899
|
-
/* $encQuote */ null
|
|
4669
|
+
__larkEncHtml, __larkStrSafe, __larkEncUri, __larkRefFn, __larkEncQuote
|
|
4900
4670
|
);
|
|
4901
4671
|
}`;
|
|
4902
4672
|
}
|
|
@@ -4910,7 +4680,7 @@ function extractGlobalVars(source) {
|
|
|
4910
4680
|
const htmlStore = {};
|
|
4911
4681
|
let htmlIndex = 0;
|
|
4912
4682
|
let lastIndex = 0;
|
|
4913
|
-
const htmlKey =
|
|
4683
|
+
const htmlKey = String.fromCharCode(5);
|
|
4914
4684
|
template.replace(
|
|
4915
4685
|
templateCmdRegExp,
|
|
4916
4686
|
(match, operate, content, offset) => {
|
|
@@ -5021,31 +4791,37 @@ function walkAst(ast, visitors) {
|
|
|
5021
4791
|
if (visitors[type]) {
|
|
5022
4792
|
visitors[type](node);
|
|
5023
4793
|
}
|
|
4794
|
+
const bag = node;
|
|
5024
4795
|
for (const key of Object.keys(node)) {
|
|
5025
4796
|
if (key === "type" || key === "start" || key === "end" || key === "loc" || key === "range")
|
|
5026
4797
|
continue;
|
|
5027
|
-
if (type === "MemberExpression" && key === "property"
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
continue;
|
|
4798
|
+
if (type === "MemberExpression" && key === "property") {
|
|
4799
|
+
const me = node;
|
|
4800
|
+
if (!me.computed) continue;
|
|
5031
4801
|
}
|
|
5032
|
-
if (type === "
|
|
5033
|
-
|
|
4802
|
+
if (type === "ObjectProperty" && key === "key") {
|
|
4803
|
+
const op = node;
|
|
4804
|
+
if (!op.computed) continue;
|
|
4805
|
+
}
|
|
4806
|
+
if (type === "ObjectMethod" && key === "key") {
|
|
4807
|
+
const om = node;
|
|
4808
|
+
if (!om.computed) continue;
|
|
5034
4809
|
}
|
|
5035
|
-
const child =
|
|
4810
|
+
const child = bag[key];
|
|
5036
4811
|
if (Array.isArray(child)) {
|
|
5037
4812
|
for (const item of child) {
|
|
5038
|
-
if (item
|
|
5039
|
-
visit(item);
|
|
5040
|
-
}
|
|
4813
|
+
if (isAstNode(item)) visit(item);
|
|
5041
4814
|
}
|
|
5042
|
-
} else if (child
|
|
4815
|
+
} else if (isAstNode(child)) {
|
|
5043
4816
|
visit(child);
|
|
5044
4817
|
}
|
|
5045
4818
|
}
|
|
5046
4819
|
}
|
|
5047
4820
|
visit(ast);
|
|
5048
4821
|
}
|
|
4822
|
+
function isAstNode(v) {
|
|
4823
|
+
return !!v && typeof v === "object" && typeof v.type === "string";
|
|
4824
|
+
}
|
|
5049
4825
|
var BUILTIN_GLOBALS = {
|
|
5050
4826
|
// ─── Template runtime helpers (injected by compileToFunction) ───────
|
|
5051
4827
|
//
|
|
@@ -5199,15 +4975,16 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
|
|
|
5199
4975
|
export {
|
|
5200
4976
|
CALL_BREAK_TIME,
|
|
5201
4977
|
Cache,
|
|
4978
|
+
cross_site_default as CrossSite,
|
|
5202
4979
|
EVENT_METHOD_REGEXP,
|
|
5203
4980
|
EventDelegator,
|
|
5204
4981
|
EventEmitter,
|
|
5205
4982
|
Frame,
|
|
4983
|
+
FrameVisualBridge,
|
|
5206
4984
|
Framework,
|
|
5207
4985
|
LARK_VIEW,
|
|
5208
4986
|
Payload,
|
|
5209
|
-
|
|
5210
|
-
ROUTER_EVENTS,
|
|
4987
|
+
RouterEvents as ROUTER_EVENTS,
|
|
5211
4988
|
Router,
|
|
5212
4989
|
SPLITTER,
|
|
5213
4990
|
Service,
|
|
@@ -5220,59 +4997,52 @@ export {
|
|
|
5220
4997
|
applyStyle,
|
|
5221
4998
|
applyVdomOps,
|
|
5222
4999
|
assign,
|
|
5223
|
-
|
|
5224
|
-
classExtend,
|
|
5225
|
-
cloneData,
|
|
5226
|
-
cloneStore,
|
|
5000
|
+
bindStore,
|
|
5227
5001
|
compileTemplate,
|
|
5228
|
-
|
|
5002
|
+
computed,
|
|
5003
|
+
create,
|
|
5229
5004
|
createVdomRef,
|
|
5230
5005
|
defineStore,
|
|
5231
|
-
|
|
5006
|
+
defineView,
|
|
5232
5007
|
encodeHTML,
|
|
5233
5008
|
encodeQ,
|
|
5234
5009
|
encodeSafe,
|
|
5235
5010
|
encodeURIExtra,
|
|
5236
5011
|
ensureElementId,
|
|
5237
5012
|
extractGlobalVars,
|
|
5013
|
+
config as frameworkConfig,
|
|
5238
5014
|
funcWithTry,
|
|
5239
5015
|
generateId,
|
|
5240
5016
|
getAttribute,
|
|
5241
5017
|
getById,
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
getUseStore,
|
|
5245
|
-
has,
|
|
5018
|
+
getRouteMode,
|
|
5019
|
+
hasOwnProperty,
|
|
5246
5020
|
installFrameVisualizerBridge,
|
|
5021
|
+
invalidateViewClass,
|
|
5247
5022
|
isPlainObject,
|
|
5248
5023
|
isPrimitive,
|
|
5249
5024
|
isPrimitiveOrFunc,
|
|
5250
|
-
isState,
|
|
5251
|
-
isStoreActive,
|
|
5252
5025
|
keys,
|
|
5253
|
-
lazySet,
|
|
5254
5026
|
mark,
|
|
5255
5027
|
markBooted,
|
|
5256
5028
|
markRouterBooted,
|
|
5257
|
-
multi,
|
|
5258
5029
|
nextCounter,
|
|
5259
5030
|
nodeInside,
|
|
5260
5031
|
noop,
|
|
5261
5032
|
now,
|
|
5262
|
-
observeCell,
|
|
5263
5033
|
parseUri,
|
|
5264
5034
|
registerViewClass,
|
|
5035
|
+
resetProjectsMap,
|
|
5265
5036
|
safeguard,
|
|
5266
5037
|
serializeFrameTree,
|
|
5267
5038
|
setData,
|
|
5268
|
-
shallowSet,
|
|
5269
|
-
mark2 as storeMark,
|
|
5270
|
-
unmark2 as storeUnmark,
|
|
5271
5039
|
syncCounter,
|
|
5272
5040
|
toMap,
|
|
5273
5041
|
toUri,
|
|
5274
5042
|
translateData,
|
|
5275
5043
|
unmark,
|
|
5044
|
+
use,
|
|
5045
|
+
useUrlState,
|
|
5276
5046
|
vdomGetCompareKey,
|
|
5277
5047
|
vdomGetNode,
|
|
5278
5048
|
vdomSetAttributes,
|