@lark.js/mvc 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6,21 +6,26 @@ var ROUTER_EVENTS = {
6
6
  CHANGED: "changed",
7
7
  PAGE_UNLOAD: "page_unload"
8
8
  };
9
- var TAG_KEY = "lark-key";
10
- var TAG_ATTR_KEY = "lark-attr-key";
11
- var TAG_VIEW_KEY = "lark-view-key";
12
- var LARK_VIEW = "lark-view";
13
- var EVT_METHOD_REG = new RegExp(
9
+ var LARK_KEYS = {
10
+ /** Attribute name: ldk (static key for skipping VDOM diff) */
11
+ DIFF_KEY: "ldk",
12
+ /** Attribute name: lak (static attribute key) */
13
+ ATTR_KEY: "lak",
14
+ /** Attribute name: lvk (view key for assign) */
15
+ VIEW_KEY: "lvk"
16
+ };
17
+ var LARK_VIEW = "v-lark";
18
+ var EVENT_METHOD_REGEXP = new RegExp(
14
19
  `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
15
20
  );
16
- var VIEW_EVT_METHOD_REG = /^(\$?)([\w]*)<(.*?)>(?:<([\w ,]*)>)?$/;
17
- var URL_TRIM_HASH_REGEX = /(?:^.*\/\/[^/]+|#.*$)/gi;
18
- var URL_TRIM_QUERY_REGEX = /^[^#]*#?!?/;
19
- var URL_PARAM_REGEX = /([^=&?/#]+)=?([^&#?]*)/g;
20
- var URL_QUERY_HASH_REGEX = /[#?].*$/;
21
+ var VIEW_EVENT_METHOD_REGEXP = /^(\$?)([\w]*)<(.*?)>(?:<([\w ,]*)>)?$/;
22
+ var URL_TRIM_HASH_REGEXP = /(?:^.*\/\/[^/]+|#.*$)/gi;
23
+ var URL_TRIM_QUERY_REGEXP = /^[^#]*#?!?/;
24
+ var URL_PARAM_REGEXP = /([^=&?/#]+)=?([^&#?]*)/g;
25
+ var URL_QUERY_HASH_REGEXP = /[#?].*$/;
21
26
  var SVG_NS = "http://www.w3.org/2000/svg";
22
27
  var MATH_NS = "http://www.w3.org/1998/Math/MathML";
23
- var TAG_NAME_REGEX = /<([a-z][^/\0>\x20\t\r\n\f]+)/i;
28
+ var TAG_NAME_REGEXP = /<([a-z][^/\0>\x20\t\r\n\f]+)/i;
24
29
  var CALL_BREAK_TIME = 48;
25
30
  function nextCounter() {
26
31
  return ++globalCounter;
@@ -158,10 +163,10 @@ function paramsReplacer(_match, name, value) {
158
163
  }
159
164
  function parseUri(uri) {
160
165
  paramsTemp = {};
161
- const path = uri.replace(URL_QUERY_HASH_REGEX, "");
166
+ const path = uri.replace(URL_QUERY_HASH_REGEXP, "");
162
167
  const pathname = path;
163
168
  const actualPath = uri === pathname && IS_URL_PARAMS.test(pathname) ? "" : pathname;
164
- uri.replace(actualPath, "").replace(URL_PARAM_REGEX, paramsReplacer);
169
+ uri.replace(actualPath, "").replace(URL_PARAM_REGEXP, paramsReplacer);
165
170
  return {
166
171
  path: actualPath,
167
172
  params: { ...paramsTemp }
@@ -201,13 +206,13 @@ function toMap(list, key) {
201
206
  function now() {
202
207
  return Date.now ? Date.now() : (/* @__PURE__ */ new Date()).getTime();
203
208
  }
204
- function classExtend(ctor, base, props, statics) {
209
+ function classExtend(make, base, props, statics) {
205
210
  const baseProto = base["prototype"] ?? {};
206
211
  const cProto = Object.create(baseProto);
207
212
  assign(cProto, props);
208
- Object.assign(ctor, statics);
209
- cProto.constructor = ctor;
210
- ctor["prototype"] = cProto;
213
+ Object.assign(make, statics);
214
+ cProto.constructor = make;
215
+ make["prototype"] = cProto;
211
216
  }
212
217
 
213
218
  // src/apply-style.ts
@@ -275,7 +280,7 @@ function unmark(host) {
275
280
  var proxiesPool = /* @__PURE__ */ new Map();
276
281
  var SAFEGUARD_SENTINEL = "_sf_";
277
282
  function safeguard(data, getter, setter, isRoot) {
278
- if (typeof window.__lark_debug === "undefined" || !window.__lark_debug) {
283
+ if (typeof window.__lark_Debug === "undefined" || !window.__lark_Debug) {
279
284
  return data;
280
285
  }
281
286
  if (typeof Proxy === "undefined") {
@@ -577,7 +582,7 @@ function teardownKeysRef(keyList) {
577
582
  if (count <= 0) {
578
583
  Reflect.deleteProperty(keyRefCounts, key);
579
584
  Reflect.deleteProperty(appData, key);
580
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
585
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
581
586
  Reflect.deleteProperty(dataWhereSet, key);
582
587
  }
583
588
  }
@@ -620,7 +625,7 @@ var State = {
620
625
  */
621
626
  get(key) {
622
627
  const result = key ? appData[key] : appData;
623
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
628
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
624
629
  return safeguard(
625
630
  result,
626
631
  (dataKey) => {
@@ -646,7 +651,7 @@ var State = {
646
651
  */
647
652
  set(data, excludes) {
648
653
  dataIsChanged = setData(data, appData, changedKeys, excludes || /* @__PURE__ */ new Set()) || dataIsChanged;
649
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug && booted) {
654
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && booted) {
650
655
  for (const p in data) {
651
656
  dataWhereSet[p] = window.location.pathname;
652
657
  }
@@ -661,7 +666,7 @@ var State = {
661
666
  State.set(data, excludes);
662
667
  }
663
668
  if (dataIsChanged) {
664
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
669
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
665
670
  for (const p in changedKeys) {
666
671
  if (has(changedKeys, p)) {
667
672
  clearNotify(p);
@@ -692,7 +697,7 @@ var State = {
692
697
  */
693
698
  clean(keys2) {
694
699
  return {
695
- ctor: function() {
700
+ make: function() {
696
701
  const keyList = setupKeysRef(keys2);
697
702
  this.on("destroy", () => {
698
703
  teardownKeysRef(keyList);
@@ -855,8 +860,8 @@ var Router = {
855
860
  if (cached) {
856
861
  return cached;
857
862
  }
858
- const srcQuery = href.replace(URL_TRIM_HASH_REGEX, "");
859
- const srcHash = href.replace(URL_TRIM_QUERY_REGEX, "");
863
+ const srcQuery = href.replace(URL_TRIM_HASH_REGEXP, "");
864
+ const srcHash = href.replace(URL_TRIM_QUERY_REGEXP, "");
860
865
  const query = parseUri(srcQuery);
861
866
  const hash = parseUri(srcHash);
862
867
  const params = assign({}, query["params"], hash["params"]);
@@ -873,7 +878,7 @@ var Router = {
873
878
  attachViewAndPath(location);
874
879
  hrefCache.set(href, location);
875
880
  }
876
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
881
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
877
882
  location["params"] = safeguard(location["params"]);
878
883
  }
879
884
  return location;
@@ -897,7 +902,7 @@ var Router = {
897
902
  );
898
903
  }
899
904
  silent = 0;
900
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug && lastChanged) {
905
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
901
906
  lastChanged = safeguard(lastChanged);
902
907
  }
903
908
  return lastChanged;
@@ -958,9 +963,9 @@ var Router = {
958
963
  join(...paths) {
959
964
  let result = paths.join("/");
960
965
  result = result.replace(/\/\.\//g, "/");
961
- const doubleDotRegex = /\/[^/]+\/\.\.\//;
962
- while (doubleDotRegex.test(result)) {
963
- result = result.replace(doubleDotRegex, "/");
966
+ const doubleDotRegExp = /\/[^/]+\/\.\.\//;
967
+ while (doubleDotRegExp.test(result)) {
968
+ result = result.replace(doubleDotRegExp, "/");
964
969
  }
965
970
  result = result.replace(/\/{2,}/g, "/");
966
971
  return result;
@@ -1062,7 +1067,7 @@ function parseEventInfo(eventInfo) {
1062
1067
  if (cached) {
1063
1068
  return assign({}, cached, { r: eventInfo });
1064
1069
  }
1065
- const match = eventInfo.match(EVT_METHOD_REG) || [];
1070
+ const match = eventInfo.match(EVENT_METHOD_REGEXP) || [];
1066
1071
  const result = {
1067
1072
  v: match[1] || "",
1068
1073
  n: match[2] || "",
@@ -1074,7 +1079,7 @@ function parseEventInfo(eventInfo) {
1074
1079
  function findFrameInfo(current, eventType) {
1075
1080
  const eventInfos = [];
1076
1081
  let begin = current;
1077
- const info = current.getAttribute(`lark-${eventType}`);
1082
+ const info = current.getAttribute(`@${eventType}`);
1078
1083
  let match;
1079
1084
  if (info) {
1080
1085
  match = parseEventInfo(info);
@@ -1119,7 +1124,7 @@ function findFrameInfo(current, eventType) {
1119
1124
  }
1120
1125
  }
1121
1126
  }
1122
- if (view.tmpl && !backtrace) {
1127
+ if (view.template && !backtrace) {
1123
1128
  if (match && !match.v) {
1124
1129
  match.v = frameId;
1125
1130
  }
@@ -1298,7 +1303,7 @@ function vdomGetNode(html, refNode) {
1298
1303
  } else if (ns === MATH_NS) {
1299
1304
  tag = "m";
1300
1305
  } else {
1301
- const match = TAG_NAME_REGEX.exec(html);
1306
+ const match = TAG_NAME_REGEXP.exec(html);
1302
1307
  tag = match ? match[1] : "";
1303
1308
  }
1304
1309
  const wrap = WrapMeta[tag] || WrapMeta["_"];
@@ -1318,7 +1323,7 @@ function vdomGetCompareKey(node) {
1318
1323
  }
1319
1324
  let key = el.autoId ? "" : el.getAttribute("id") || void 0;
1320
1325
  if (!key) {
1321
- key = el.getAttribute(TAG_KEY) || void 0;
1326
+ key = el.getAttribute(LARK_KEYS.DIFF_KEY) || void 0;
1322
1327
  }
1323
1328
  if (!key) {
1324
1329
  const larkView = el.getAttribute(LARK_VIEW);
@@ -1446,17 +1451,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1446
1451
  }
1447
1452
  }
1448
1453
  function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1449
- if (vdomSpecialDiff(oldNode, newNode) || oldNode.nodeType === 1 && oldNode.hasAttribute(TAG_VIEW_KEY) || !(oldNode.isEqualNode && oldNode.isEqualNode(newNode))) {
1454
+ if (vdomSpecialDiff(oldNode, newNode) || oldNode.nodeType === 1 && oldNode.hasAttribute(LARK_KEYS.VIEW_KEY) || !(oldNode.isEqualNode && oldNode.isEqualNode(newNode))) {
1450
1455
  if (oldNode.nodeType === newNode.nodeType && oldNode.nodeName === newNode.nodeName) {
1451
1456
  if (oldNode.nodeType === 1) {
1452
1457
  const oldEl = oldNode;
1453
1458
  const newEl = newNode;
1454
- const staticKey = newEl.getAttribute(TAG_KEY);
1455
- if (staticKey && staticKey === oldEl.getAttribute(TAG_KEY)) {
1459
+ const staticKey = newEl.getAttribute(LARK_KEYS.DIFF_KEY);
1460
+ if (staticKey && staticKey === oldEl.getAttribute(LARK_KEYS.DIFF_KEY)) {
1456
1461
  return;
1457
1462
  }
1458
1463
  const newLarkView = newEl.getAttribute(LARK_VIEW);
1459
- const updateAttribute = !newEl.getAttribute(TAG_ATTR_KEY) || newEl.getAttribute(TAG_ATTR_KEY) !== oldEl.getAttribute(TAG_ATTR_KEY);
1464
+ const updateAttribute = !newEl.getAttribute(LARK_KEYS.ATTR_KEY) || newEl.getAttribute(LARK_KEYS.ATTR_KEY) !== oldEl.getAttribute(LARK_KEYS.ATTR_KEY);
1460
1465
  let updateChildren = true;
1461
1466
  if (newLarkView) {
1462
1467
  const oldFrameId = oldEl.getAttribute("id") || "";
@@ -1527,10 +1532,10 @@ var EncoderMap = {
1527
1532
  "'": "#39",
1528
1533
  "`": "#96"
1529
1534
  };
1530
- var ENCODE_REGEX = /[&<>"'`]/g;
1535
+ var ENCODE_REGEXP = /[&<>"'`]/g;
1531
1536
  function encodeHTML(v) {
1532
1537
  return String(v == null ? "" : v).replace(
1533
- ENCODE_REGEX,
1538
+ ENCODE_REGEXP,
1534
1539
  (m) => "&" + EncoderMap[m] + ";"
1535
1540
  );
1536
1541
  }
@@ -1544,16 +1549,16 @@ var URIMap = {
1544
1549
  ")": "%29",
1545
1550
  "*": "%2A"
1546
1551
  };
1547
- var URI_ENCODE_REGEX = /[!')(*]/g;
1552
+ var URI_ENCODE_REGEXP = /[!')(*]/g;
1548
1553
  function encodeURIExtra(v) {
1549
1554
  return encodeURIComponent(encodeSafe(v)).replace(
1550
- URI_ENCODE_REGEX,
1555
+ URI_ENCODE_REGEXP,
1551
1556
  (m) => URIMap[m]
1552
1557
  );
1553
1558
  }
1554
- var QUOTE_REGEX = /['"\\]/g;
1559
+ var QUOTE_REGEXP = /['"\\]/g;
1555
1560
  function encodeQ(v) {
1556
- return encodeSafe(v).replace(QUOTE_REGEX, "\\$&");
1561
+ return encodeSafe(v).replace(QUOTE_REGEXP, "\\$&");
1557
1562
  }
1558
1563
 
1559
1564
  // src/updater.ts
@@ -1601,7 +1606,7 @@ var Updater = class {
1601
1606
  if (key) {
1602
1607
  result = this.data[key];
1603
1608
  }
1604
- if (typeof window !== "undefined" && window.__lark_debug) {
1609
+ if (typeof window !== "undefined" && window.__lark_Debug) {
1605
1610
  return safeguard(result);
1606
1611
  }
1607
1612
  return result;
@@ -1652,9 +1657,9 @@ var Updater = class {
1652
1657
  const view = frame?.view;
1653
1658
  const node = getById(this.viewId);
1654
1659
  if (changed && view && node && view.signature > 0) {
1655
- const tmpl = view.tmpl;
1656
- if (tmpl && typeof tmpl === "function") {
1657
- const html = tmpl(
1660
+ const template = view.template;
1661
+ if (template && typeof template === "function") {
1662
+ const html = template(
1658
1663
  this.data,
1659
1664
  this.viewId,
1660
1665
  this.refData,
@@ -1736,10 +1741,10 @@ var Updater = class {
1736
1741
  // src/view.ts
1737
1742
  var VIEW_GLOBALS = {};
1738
1743
  if (typeof window !== "undefined") {
1739
- VIEW_GLOBALS["win"] = window;
1744
+ VIEW_GLOBALS["window"] = window;
1740
1745
  }
1741
1746
  if (typeof document !== "undefined") {
1742
- VIEW_GLOBALS["doc"] = document;
1747
+ VIEW_GLOBALS["document"] = document;
1743
1748
  }
1744
1749
  function viewPrepare(oView) {
1745
1750
  if (oView.ctors) {
@@ -1759,7 +1764,7 @@ function viewPrepare(oView) {
1759
1764
  if (!has(proto, p)) continue;
1760
1765
  const currentFn = proto[p];
1761
1766
  if (typeof currentFn !== "function") continue;
1762
- const matches = p.match(VIEW_EVT_METHOD_REG);
1767
+ const matches = p.match(VIEW_EVENT_METHOD_REGEXP);
1763
1768
  if (!matches) continue;
1764
1769
  const isSelector = matches[1];
1765
1770
  const selectorOrCallback = matches[2];
@@ -1866,11 +1871,11 @@ function viewMergeMixins(mixins, viewClass, ctors) {
1866
1871
  if (!has(node, p)) continue;
1867
1872
  const fn = node[p];
1868
1873
  const exist = temp[p];
1869
- if (p === "ctor") {
1874
+ if (p === "make") {
1870
1875
  ctors.push(fn);
1871
1876
  continue;
1872
1877
  }
1873
- if (VIEW_EVT_METHOD_REG.test(p)) {
1878
+ if (VIEW_EVENT_METHOD_REGEXP.test(p)) {
1874
1879
  if (exist) {
1875
1880
  temp[p] = processMixinsSameEvent(fn, exist);
1876
1881
  } else {
@@ -1968,7 +1973,7 @@ var View = class _View {
1968
1973
  /** Whether rendered at least once */
1969
1974
  rendered;
1970
1975
  /** Whether view has template */
1971
- tmpl;
1976
+ template;
1972
1977
  /** Location observation config */
1973
1978
  locationObserved = {
1974
1979
  flag: 0,
@@ -2203,23 +2208,23 @@ var View = class _View {
2203
2208
  * Extend View to create a new View subclass.
2204
2209
  *
2205
2210
  * Supports:
2206
- * - props.ctor: constructor-like init (called with initParams + {node, deep})
2211
+ * - props.make: constructor-like init (called with initParams + {node, deep})
2207
2212
  * - props.mixins: array of mixin objects
2208
2213
  * - Event method patterns: `'name<click>'` etc.
2209
2214
  */
2210
2215
  static extend(props, statics) {
2211
2216
  props = props || {};
2212
- const ctor = props["ctor"];
2217
+ const make = props["make"];
2213
2218
  const ctors = [];
2214
- if (ctor) {
2215
- ctors.push(ctor);
2219
+ if (make) {
2220
+ ctors.push(make);
2216
2221
  }
2217
2222
  const ParentView = this;
2218
2223
  const ChildView = class extends ParentView {
2219
2224
  constructor(nodeId, ownerFrame, initParams, node, mixinCtors) {
2220
2225
  super(nodeId, ownerFrame, initParams, node, []);
2221
2226
  for (const key in props) {
2222
- if (has(props, key) && key !== "ctor") {
2227
+ if (has(props, key) && key !== "make") {
2223
2228
  this[key] = props[key];
2224
2229
  }
2225
2230
  }
@@ -2230,7 +2235,7 @@ var View = class _View {
2230
2235
  initParams,
2231
2236
  {
2232
2237
  node,
2233
- deep: !this.tmpl
2238
+ deep: !this.template
2234
2239
  }
2235
2240
  ];
2236
2241
  const concatCtors = ctors.concat(mixinCtors || []);
@@ -2241,7 +2246,7 @@ var View = class _View {
2241
2246
  };
2242
2247
  const proto = ChildView.prototype;
2243
2248
  for (const key in props) {
2244
- if (has(props, key) && key !== "ctor") {
2249
+ if (has(props, key) && key !== "make") {
2245
2250
  proto[key] = props[key];
2246
2251
  }
2247
2252
  }
@@ -2320,7 +2325,7 @@ var Frame = class _Frame extends EventEmitter {
2320
2325
  hasAltered = 0;
2321
2326
  /** Whether view is destroyed */
2322
2327
  destroyed = 0;
2323
- /** View path (lark-view attribute value) */
2328
+ /** View path (v-lark attribute value) */
2324
2329
  viewPath;
2325
2330
  /** Original template before mount */
2326
2331
  originalTemplate;
@@ -2358,8 +2363,8 @@ var Frame = class _Frame extends EventEmitter {
2358
2363
  * 5. Create View instance
2359
2364
  * 6. View_DelegateEvents (bind DOM events)
2360
2365
  * 7. Call view.init()
2361
- * 8. If view has tmpl, call render via Updater
2362
- * 9. If no tmpl, call endUpdate directly
2366
+ * 8. If view has template, call render via Updater
2367
+ * 9. If no template, call endUpdate directly
2363
2368
  */
2364
2369
  mountView(viewPath, viewInitParams) {
2365
2370
  const node = document.getElementById(this.id);
@@ -2403,14 +2408,14 @@ var Frame = class _Frame extends EventEmitter {
2403
2408
  viewDelegateEvents(view);
2404
2409
  const initResult = funcWithTry(
2405
2410
  view.init,
2406
- [params, { node, deep: !view.tmpl }],
2411
+ [params, { node, deep: !view.template }],
2407
2412
  view,
2408
2413
  noop
2409
2414
  );
2410
2415
  const nextSign = ++this.signature;
2411
2416
  Promise.resolve(initResult).then(() => {
2412
2417
  if (nextSign !== this.signature) return;
2413
- if (view.tmpl) {
2418
+ if (view.template) {
2414
2419
  const renderFn = view.$b;
2415
2420
  if (renderFn) {
2416
2421
  renderFn.call(view);
@@ -3047,6 +3052,114 @@ function serviceSend(service, attrs, done, flag, save) {
3047
3052
  }
3048
3053
  }
3049
3054
 
3055
+ // src/frame-visualizer/index.ts
3056
+ var MSG_PING = "LARK_VIS_PING";
3057
+ var MSG_PONG = "LARK_VIS_PONG";
3058
+ var MSG_REQUEST_TREE = "LARK_VIS_REQUEST_TREE";
3059
+ var MSG_TREE = "LARK_VIS_TREE";
3060
+ var MSG_TREE_DELTA = "LARK_VIS_TREE_DELTA";
3061
+ function serializeView(view) {
3062
+ return {
3063
+ id: view.id,
3064
+ rendered: !!view.rendered,
3065
+ signature: view.signature,
3066
+ observedStateKeys: view.observedStateKeys ?? null,
3067
+ locationObserved: {
3068
+ flag: view.locationObserved.flag,
3069
+ keys: view.locationObserved.keys,
3070
+ observePath: view.locationObserved.observePath
3071
+ },
3072
+ hasTemplate: !!view.template
3073
+ };
3074
+ }
3075
+ function serializeFrame(frameId) {
3076
+ const frame = Frame.get(frameId);
3077
+ if (!frame) return null;
3078
+ const view = frame.view;
3079
+ const children = [];
3080
+ for (const childId of frame.children()) {
3081
+ const childNode = serializeFrame(childId);
3082
+ if (childNode) {
3083
+ children.push(childNode);
3084
+ }
3085
+ }
3086
+ return {
3087
+ id: frame.id,
3088
+ parentId: frame.parentId ?? null,
3089
+ viewPath: frame.viewPath ?? null,
3090
+ childrenCount: frame.childrenCount,
3091
+ readyCount: frame.readyCount,
3092
+ childrenCreated: frame.childrenCreated,
3093
+ childrenAlter: frame.childrenAlter,
3094
+ destroyed: frame.destroyed,
3095
+ view: view ? serializeView(view) : null,
3096
+ children
3097
+ };
3098
+ }
3099
+ function serializeFrameTree() {
3100
+ const root = Frame.root();
3101
+ const rootNode = serializeFrame(root.id);
3102
+ let totalFrames = 0;
3103
+ const countFrames = (node) => {
3104
+ if (!node) return;
3105
+ totalFrames++;
3106
+ for (const child of node.children) {
3107
+ countFrames(child);
3108
+ }
3109
+ };
3110
+ countFrames(rootNode);
3111
+ return {
3112
+ root: rootNode,
3113
+ totalFrames,
3114
+ timestamp: Date.now(),
3115
+ rootId: root.id
3116
+ };
3117
+ }
3118
+ var bridgeInstalled = false;
3119
+ var lastTreeJson = "";
3120
+ function installFrameVisualizerBridge() {
3121
+ if (bridgeInstalled) return;
3122
+ if (typeof window === "undefined") return;
3123
+ bridgeInstalled = true;
3124
+ window.addEventListener("message", (event) => {
3125
+ const data = event.data;
3126
+ if (!data || typeof data !== "object") return;
3127
+ const type = data.type;
3128
+ if (type === MSG_PING) {
3129
+ const source = event.source;
3130
+ if (source) {
3131
+ source.postMessage({ type: MSG_PONG }, { targetOrigin: "*" });
3132
+ }
3133
+ return;
3134
+ }
3135
+ if (type === MSG_REQUEST_TREE) {
3136
+ const tree = serializeFrameTree();
3137
+ const source = event.source;
3138
+ if (source) {
3139
+ source.postMessage(
3140
+ { type: MSG_TREE, data: tree },
3141
+ { targetOrigin: "*" }
3142
+ );
3143
+ }
3144
+ }
3145
+ });
3146
+ Frame.on("add", () => {
3147
+ pushTreeUpdate();
3148
+ });
3149
+ Frame.on("remove", () => {
3150
+ pushTreeUpdate();
3151
+ });
3152
+ }
3153
+ function pushTreeUpdate() {
3154
+ if (window === window.parent) return;
3155
+ const tree = serializeFrameTree();
3156
+ const treeJson = JSON.stringify(tree);
3157
+ if (treeJson !== lastTreeJson) {
3158
+ lastTreeJson = treeJson;
3159
+ window.parent.postMessage({ type: MSG_TREE_DELTA, data: tree }, "*");
3160
+ }
3161
+ }
3162
+
3050
3163
  // src/framework.ts
3051
3164
  var config = {
3052
3165
  rootId: "lark-root",
@@ -3253,10 +3366,11 @@ var Framework = {
3253
3366
  booted3 = true;
3254
3367
  markBooted();
3255
3368
  markRouterBooted();
3369
+ installFrameVisualizerBridge();
3256
3370
  const rootFrame2 = Frame.root(config.rootId);
3257
3371
  Router._bind();
3258
3372
  const defaultView = config.defaultView || "";
3259
- if (defaultView) {
3373
+ if (defaultView && !rootFrame2.view) {
3260
3374
  rootFrame2.mountView(defaultView);
3261
3375
  }
3262
3376
  },
@@ -3685,20 +3799,20 @@ function createState(initialData, config2) {
3685
3799
  lazySet(state, initialData);
3686
3800
  return state;
3687
3801
  }
3688
- var currLazySetKey = null;
3802
+ var curLazySetKey = null;
3689
3803
  function lazySet(target, data) {
3690
3804
  if (isObject(data)) {
3691
3805
  Reflect.ownKeys(data).forEach((key) => {
3692
3806
  const strKey = key;
3693
- if (currLazySetKey) throw new Error("[lark-store] lazy set key conflict");
3694
- currLazySetKey = strKey;
3807
+ if (curLazySetKey) throw new Error("[lark-store] lazy set key conflict");
3808
+ curLazySetKey = strKey;
3695
3809
  target[strKey] = data[strKey];
3696
3810
  });
3697
3811
  }
3698
3812
  }
3699
3813
  function isLazySet(property) {
3700
- if (currLazySetKey === property) {
3701
- currLazySetKey = "";
3814
+ if (curLazySetKey === property) {
3815
+ curLazySetKey = "";
3702
3816
  return true;
3703
3817
  }
3704
3818
  return false;
@@ -4192,7 +4306,7 @@ function multi(useStore) {
4192
4306
  return useFn(view);
4193
4307
  });
4194
4308
  const mixinObj = {
4195
- ctor() {
4309
+ make() {
4196
4310
  if (!rootViewPath) {
4197
4311
  const owner = this["owner"];
4198
4312
  rootViewPath = owner?.["path"] || "";
@@ -4216,9 +4330,9 @@ function jsObjectToUrlParams(paramsStr) {
4216
4330
  if (objMatch) {
4217
4331
  const inner = objMatch[1];
4218
4332
  const pairs = [];
4219
- const pairRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|([^,}]+))/g;
4333
+ const pairRegExp = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|([^,}]+))/g;
4220
4334
  let m;
4221
- while ((m = pairRegex.exec(inner)) !== null) {
4335
+ while ((m = pairRegExp.exec(inner)) !== null) {
4222
4336
  const key = m[1];
4223
4337
  const value = m[2] ?? m[3] ?? m[4]?.trim() ?? "";
4224
4338
  pairs.push(`${key}=${value}`);
@@ -4240,19 +4354,19 @@ function restoreComments(source, comments) {
4240
4354
  return comments[parseInt(index, 10)];
4241
4355
  });
4242
4356
  }
4243
- function processLarkEvents(source) {
4357
+ function processViewEvents(source) {
4244
4358
  return source.replace(
4245
- /lark-(\w+)="([^"]+)"/g,
4359
+ /@(\w+)="([^"]+)"/g,
4246
4360
  (fullAttr, eventName, attrValue) => {
4247
4361
  const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
4248
4362
  if (!eventMatch) return fullAttr;
4249
4363
  const handlerName = eventMatch[1];
4250
4364
  const paramsStr = eventMatch[2].trim();
4251
4365
  if (!paramsStr) {
4252
- return `lark-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4366
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4253
4367
  }
4254
4368
  const urlParams = jsObjectToUrlParams(paramsStr);
4255
- return `lark-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4369
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4256
4370
  }
4257
4371
  );
4258
4372
  }
@@ -4325,7 +4439,7 @@ function convertArtSyntax(source, debug) {
4325
4439
  }
4326
4440
  if (blockStack.length > 0) {
4327
4441
  const unclosed = blockStack.map((b) => `"${b.ctrl}" at line ${b.line}`).join(", ");
4328
- throw new Error(`[Lark Error(tmpl-art)] unclosed block(s): ${unclosed}`);
4442
+ throw new Error(`[@lark/mvc error] unclosed block(s): ${unclosed}`);
4329
4443
  }
4330
4444
  return result.join("");
4331
4445
  }
@@ -4424,7 +4538,7 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
4424
4538
  const object = tokens[0];
4425
4539
  if (tokens.length > 1 && tokens[1] !== "as") {
4426
4540
  throw new Error(
4427
- `[Lark Error(tmpl-art)] bad each syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{each list as item [index]}}`
4541
+ `[@lark/mvc error] bad each syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{each list as item [index]}}`
4428
4542
  );
4429
4543
  }
4430
4544
  const restTokens = tokens.slice(2);
@@ -4446,12 +4560,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
4446
4560
  }
4447
4561
  return `${debugPrefix}<%for(let ${index}=0${refExpr},${refObjCount}=${refObj}.length${lastCount};${index}<${refObjCount};${index}++){${firstAndLast}${valueDecl}%>`;
4448
4562
  }
4449
- case "forin": {
4450
- blockStack.push({ ctrl: "forin", line: lineNo });
4563
+ case "parse": {
4564
+ blockStack.push({ ctrl: "parse", line: lineNo });
4451
4565
  const object = tokens[0];
4452
4566
  if (tokens.length > 1 && tokens[1] !== "as") {
4453
4567
  throw new Error(
4454
- `[Lark Error(tmpl-art)] bad forin syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{forin obj as val [key]}}`
4568
+ `[@lark/mvc error] bad parse syntax: {{${code}}}. Expected "as" keyword, got "${tokens[1]}". Usage: {{for-in obj as val [key]}}`
4455
4569
  );
4456
4570
  }
4457
4571
  const restTokens2 = tokens.slice(2);
@@ -4472,18 +4586,18 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
4472
4586
  return `${debugPrefix}<%let ${tokens.join(" ")};%>`;
4473
4587
  case "/if":
4474
4588
  case "/each":
4475
- case "/forin":
4589
+ case "/parse":
4476
4590
  case "/for": {
4477
4591
  const expectedCtrl = keyword.substring(1);
4478
4592
  const last = blockStack.pop();
4479
4593
  if (!last) {
4480
4594
  throw new Error(
4481
- `[Lark Error(tmpl-art)] unexpected {{${code}}}: no matching open block`
4595
+ `[@lark/mvc error] unexpected {{${code}}}: no matching open block`
4482
4596
  );
4483
4597
  }
4484
4598
  if (last.ctrl !== expectedCtrl) {
4485
4599
  throw new Error(
4486
- `[Lark Error(tmpl-art)] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4600
+ `[@lark/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4487
4601
  );
4488
4602
  }
4489
4603
  return `${debugPrefix}<%}%>`;
@@ -4560,12 +4674,12 @@ function compileToFunction(source, debug, file) {
4560
4674
  index - 2
4561
4675
  );
4562
4676
  const x11 = String.fromCharCode(17);
4563
- const artReg = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
4564
- const artM = expr.match(artReg);
4677
+ const artRegExp = new RegExp(`^'(\\d+)${x11}([^${x11}]+)${x11}'$`);
4678
+ const artM = expr.match(artRegExp);
4565
4679
  let art = "";
4566
4680
  let line = -1;
4567
4681
  if (artM) {
4568
- expr = expr.replace(artReg, "");
4682
+ expr = expr.replace(artRegExp, "");
4569
4683
  art = artM[2];
4570
4684
  line = parseInt(artM[1], 10);
4571
4685
  } else {
@@ -4624,8 +4738,8 @@ function compileToFunction(source, debug, file) {
4624
4738
  const filePart = file ? `\\r\\n\\tat file:${file}` : "";
4625
4739
  funcSource = `let $expr,$art,$line;try{${funcSource}}catch(ex){let msg='render view error:'+(ex.message||ex);if($art)msg+='\\r\\n\\tsrc art:{{'+$art+'}}\\r\\n\\tat line:'+$line;msg+='\\r\\n\\t'+($art?'translate to:':'expr:');msg+=$expr+'${filePart}';throw msg;}`;
4626
4740
  }
4627
- const viewIdReg = new RegExp(String.fromCharCode(31), "g");
4628
- funcSource = funcSource.replace(viewIdReg, `'+$viewId+'`);
4741
+ const viewIdRegExp = new RegExp(String.fromCharCode(31), "g");
4742
+ funcSource = funcSource.replace(viewIdRegExp, `'+$viewId+'`);
4629
4743
  const atRule = hasAtRule ? `if(!$i){$i=(ref,v,k,f)=>{for(f=ref[$g];--f;)if(ref[k=$g+f]===v)return k;ref[k=$g+ref[$g]++]=v;return k;}}` : "";
4630
4744
  const encode = `if(!$n){let $em={'&':'amp','<':'lt','>':'gt','"':'#34','\\'':'#39','\`':'#96'},$er=/[&<>"'\`]/g,$ef=m=>'&'+$em[m]+';';$n=v=>''+(v==null?'':v);$e=v=>$n(v).replace($er,$ef)}`;
4631
4745
  const encodeURIMore = `if(!$eu){let $um={'!':'%21','\\'':'%27','(':'%28',')':'%29','*':'%2A'},$uf=m=>$um[m],$uq=/[!')(*]/g;$eu=v=>encodeURIComponent($n(v)).replace($uq,$uf)}`;
@@ -4639,8 +4753,8 @@ function compileTemplate(source, options = {}) {
4639
4753
  const { debug = false, globalVars = [], file } = options;
4640
4754
  const { protectedSource, comments } = protectComments(source);
4641
4755
  const converted = convertArtSyntax(protectedSource, debug);
4642
- const larkEventProcessed = processLarkEvents(converted);
4643
- const finalSource = restoreComments(larkEventProcessed, comments);
4756
+ const viewEventProcessed = processViewEvents(converted);
4757
+ const finalSource = restoreComments(viewEventProcessed, comments);
4644
4758
  const funcBody = compileToFunction(finalSource, debug, file);
4645
4759
  const varDeclarations = globalVars.map((key) => `,${key}=$$.${key}`).join("");
4646
4760
  const funcWithVars = funcBody.replace("{{VARS}}", () => varDeclarations);
@@ -4658,20 +4772,20 @@ function compileTemplate(source, options = {}) {
4658
4772
  }
4659
4773
  function extractGlobalVars(source) {
4660
4774
  const { protectedSource, comments: _comments } = protectComments(source);
4661
- const larkEventProcessed = processLarkEvents(protectedSource);
4662
- const converted = convertArtSyntax(larkEventProcessed, false);
4663
- const tmpl = restoreComments(converted, _comments);
4664
- const tmplCmdReg = /<%([@=!:])?([\s\S]*?)%>|$/g;
4775
+ const viewEventProcessed = processViewEvents(protectedSource);
4776
+ const converted = convertArtSyntax(viewEventProcessed, false);
4777
+ const template = restoreComments(converted, _comments);
4778
+ const templateCmdRegExp = /<%([@=!:])?([\s\S]*?)%>|$/g;
4665
4779
  const fnParts = [];
4666
4780
  const htmlStore = {};
4667
4781
  let htmlIndex = 0;
4668
4782
  let lastIndex = 0;
4669
4783
  const htmlKey = "";
4670
- tmpl.replace(
4671
- tmplCmdReg,
4784
+ template.replace(
4785
+ templateCmdRegExp,
4672
4786
  (match, operate, content, offset) => {
4673
4787
  const start = operate ? 3 : 2;
4674
- const htmlText = tmpl.substring(lastIndex, offset + start);
4788
+ const htmlText = template.substring(lastIndex, offset + start);
4675
4789
  const key = htmlKey + htmlIndex++ + htmlKey;
4676
4790
  htmlStore[key] = htmlText;
4677
4791
  lastIndex = offset + match.length - 2;
@@ -4756,17 +4870,17 @@ function extractGlobalVars(source) {
4756
4870
  }
4757
4871
  function fallbackExtractVariables(source) {
4758
4872
  const vars = /* @__PURE__ */ new Set();
4759
- const outputReg = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4873
+ const outputRegExp = /\{\{[:=!@]\s*([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4760
4874
  let m;
4761
- while ((m = outputReg.exec(source)) !== null) {
4875
+ while ((m = outputRegExp.exec(source)) !== null) {
4762
4876
  vars.add(m[1]);
4763
4877
  }
4764
- const eachReg = /\{\{each\s+([a-zA-Z_$][\w$]*)\s+as/g;
4765
- while ((m = eachReg.exec(source)) !== null) {
4878
+ const eachRegExp = /\{\{each\s+([a-zA-Z_$][\w$]*)\s+as/g;
4879
+ while ((m = eachRegExp.exec(source)) !== null) {
4766
4880
  vars.add(m[1]);
4767
4881
  }
4768
- const ifReg = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4769
- while ((m = ifReg.exec(source)) !== null) {
4882
+ const ifRegExp = /\{\{(?:else\s+)?if\s+([a-zA-Z_$][\w$]*)[^}]*\}\}/g;
4883
+ while ((m = ifRegExp.exec(source)) !== null) {
4770
4884
  vars.add(m[1]);
4771
4885
  }
4772
4886
  return Array.from(vars).filter((v) => !BUILTIN_GLOBAL_SET.has(v));
@@ -4829,7 +4943,7 @@ var BUILTIN_GLOBALS = {
4829
4943
  // {'&':'amp','<':'gt','>':'gt','"':'#34','\'':'#39','`':'#96'}
4830
4944
  // Not a standalone function; referenced inside $e's closure.
4831
4945
  $em: 1,
4832
- // HTML entity RegExp — internal regex used by $e:
4946
+ // HTML entity RegExp — internal regexp used by $e:
4833
4947
  // /[&<>"'`]/g
4834
4948
  $er: 1,
4835
4949
  // HTML entity replacer function — internal helper used by $e:
@@ -4843,19 +4957,18 @@ var BUILTIN_GLOBALS = {
4843
4957
  // Reference lookup: (refData, value) => key
4844
4958
  // Finds or allocates a SPLITTER-prefixed key in refData for a given
4845
4959
  // object reference. Used by {{@ref}} operator for passing object
4846
- // references to child views via lark-view attributes.
4847
- // Aligned with mx.js Updater_Ref.
4960
+ // references to child views via v-lark attributes.
4848
4961
  $i: 1,
4849
4962
  // URI encoder: v => encodeURIComponent($n(v)).replace(/[!')(*]/g, extraMap)
4850
4963
  // Extends encodeURIComponent with encoding of ! ' ( ) *.
4851
- // Applied to values in lark-event URL parameters and {{!uri}} contexts.
4964
+ // Applied to values in @event URL parameters and {{!uri}} contexts.
4852
4965
  $eu: 1,
4853
4966
  // Quote encoder: v => $n(v).replace(/['"\\]/g, '\\$&')
4854
4967
  // Escapes quotes and backslashes for safe embedding in HTML attribute
4855
4968
  // values (e.g. data-json='...').
4856
4969
  $eq: 1,
4857
4970
  // View ID — the unique identifier of the owning View instance.
4858
- // Injected into lark-event attribute values at render time so that
4971
+ // Injected into @event attribute values at render time so that
4859
4972
  // EventDelegator can dispatch events to the correct View handler.
4860
4973
  // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
4861
4974
  $viewId: 1,
@@ -4945,7 +5058,7 @@ export {
4945
5058
  Bag,
4946
5059
  CALL_BREAK_TIME,
4947
5060
  Cache,
4948
- EVT_METHOD_REG,
5061
+ EVENT_METHOD_REGEXP,
4949
5062
  EventDelegator,
4950
5063
  EventEmitter,
4951
5064
  Frame,
@@ -4957,12 +5070,9 @@ export {
4957
5070
  SPLITTER,
4958
5071
  Service,
4959
5072
  State,
4960
- TAG_ATTR_KEY,
4961
- TAG_KEY,
4962
- TAG_NAME_REGEX,
4963
- TAG_VIEW_KEY,
5073
+ TAG_NAME_REGEXP,
4964
5074
  Updater,
4965
- VIEW_EVT_METHOD_REG,
5075
+ VIEW_EVENT_METHOD_REGEXP,
4966
5076
  View,
4967
5077
  applyIdUpdates,
4968
5078
  applyStyle,
@@ -4991,6 +5101,7 @@ export {
4991
5101
  getStore,
4992
5102
  getUseStore,
4993
5103
  has,
5104
+ installFrameVisualizerBridge,
4994
5105
  isArray,
4995
5106
  isPlainObject,
4996
5107
  isPrimitive,
@@ -5011,6 +5122,7 @@ export {
5011
5122
  parseUri,
5012
5123
  registerViewClass,
5013
5124
  safeguard,
5125
+ serializeFrameTree,
5014
5126
  setData,
5015
5127
  shallowSet,
5016
5128
  mark2 as storeMark,