@lark.js/mvc 0.0.2 → 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.cjs CHANGED
@@ -35,10 +35,7 @@ __export(index_exports, {
35
35
  SPLITTER: () => SPLITTER,
36
36
  Service: () => Service,
37
37
  State: () => State,
38
- TAG_ATTR_KEY: () => TAG_ATTR_KEY,
39
- TAG_KEY: () => TAG_KEY,
40
38
  TAG_NAME_REGEXP: () => TAG_NAME_REGEXP,
41
- TAG_VIEW_KEY: () => TAG_VIEW_KEY,
42
39
  Updater: () => Updater,
43
40
  VIEW_EVENT_METHOD_REGEXP: () => VIEW_EVENT_METHOD_REGEXP,
44
41
  View: () => View,
@@ -69,6 +66,7 @@ __export(index_exports, {
69
66
  getStore: () => getStore,
70
67
  getUseStore: () => getUseStore,
71
68
  has: () => has,
69
+ installFrameVisualizerBridge: () => installFrameVisualizerBridge,
72
70
  isArray: () => isArray,
73
71
  isPlainObject: () => isPlainObject,
74
72
  isPrimitive: () => isPrimitive,
@@ -89,6 +87,7 @@ __export(index_exports, {
89
87
  parseUri: () => parseUri,
90
88
  registerViewClass: () => registerViewClass,
91
89
  safeguard: () => safeguard,
90
+ serializeFrameTree: () => serializeFrameTree,
92
91
  setData: () => setData,
93
92
  shallowSet: () => shallowSet,
94
93
  storeMark: () => mark2,
@@ -116,10 +115,15 @@ var ROUTER_EVENTS = {
116
115
  CHANGED: "changed",
117
116
  PAGE_UNLOAD: "page_unload"
118
117
  };
119
- var TAG_KEY = "lark-key";
120
- var TAG_ATTR_KEY = "lark-attr-key";
121
- var TAG_VIEW_KEY = "lark-view-key";
122
- var LARK_VIEW = "lark-view";
118
+ var LARK_KEYS = {
119
+ /** Attribute name: ldk (static key for skipping VDOM diff) */
120
+ DIFF_KEY: "ldk",
121
+ /** Attribute name: lak (static attribute key) */
122
+ ATTR_KEY: "lak",
123
+ /** Attribute name: lvk (view key for assign) */
124
+ VIEW_KEY: "lvk"
125
+ };
126
+ var LARK_VIEW = "v-lark";
123
127
  var EVENT_METHOD_REGEXP = new RegExp(
124
128
  `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
125
129
  );
@@ -311,13 +315,13 @@ function toMap(list, key) {
311
315
  function now() {
312
316
  return Date.now ? Date.now() : (/* @__PURE__ */ new Date()).getTime();
313
317
  }
314
- function classExtend(ctor, base, props, statics) {
318
+ function classExtend(make, base, props, statics) {
315
319
  const baseProto = base["prototype"] ?? {};
316
320
  const cProto = Object.create(baseProto);
317
321
  assign(cProto, props);
318
- Object.assign(ctor, statics);
319
- cProto.constructor = ctor;
320
- ctor["prototype"] = cProto;
322
+ Object.assign(make, statics);
323
+ cProto.constructor = make;
324
+ make["prototype"] = cProto;
321
325
  }
322
326
 
323
327
  // src/apply-style.ts
@@ -385,7 +389,7 @@ function unmark(host) {
385
389
  var proxiesPool = /* @__PURE__ */ new Map();
386
390
  var SAFEGUARD_SENTINEL = "_sf_";
387
391
  function safeguard(data, getter, setter, isRoot) {
388
- if (typeof window.__lark_debug === "undefined" || !window.__lark_debug) {
392
+ if (typeof window.__lark_Debug === "undefined" || !window.__lark_Debug) {
389
393
  return data;
390
394
  }
391
395
  if (typeof Proxy === "undefined") {
@@ -687,7 +691,7 @@ function teardownKeysRef(keyList) {
687
691
  if (count <= 0) {
688
692
  Reflect.deleteProperty(keyRefCounts, key);
689
693
  Reflect.deleteProperty(appData, key);
690
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
694
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
691
695
  Reflect.deleteProperty(dataWhereSet, key);
692
696
  }
693
697
  }
@@ -730,7 +734,7 @@ var State = {
730
734
  */
731
735
  get(key) {
732
736
  const result = key ? appData[key] : appData;
733
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
737
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
734
738
  return safeguard(
735
739
  result,
736
740
  (dataKey) => {
@@ -756,7 +760,7 @@ var State = {
756
760
  */
757
761
  set(data, excludes) {
758
762
  dataIsChanged = setData(data, appData, changedKeys, excludes || /* @__PURE__ */ new Set()) || dataIsChanged;
759
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug && booted) {
763
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && booted) {
760
764
  for (const p in data) {
761
765
  dataWhereSet[p] = window.location.pathname;
762
766
  }
@@ -771,7 +775,7 @@ var State = {
771
775
  State.set(data, excludes);
772
776
  }
773
777
  if (dataIsChanged) {
774
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
778
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
775
779
  for (const p in changedKeys) {
776
780
  if (has(changedKeys, p)) {
777
781
  clearNotify(p);
@@ -802,7 +806,7 @@ var State = {
802
806
  */
803
807
  clean(keys2) {
804
808
  return {
805
- ctor: function() {
809
+ make: function() {
806
810
  const keyList = setupKeysRef(keys2);
807
811
  this.on("destroy", () => {
808
812
  teardownKeysRef(keyList);
@@ -983,7 +987,7 @@ var Router = {
983
987
  attachViewAndPath(location);
984
988
  hrefCache.set(href, location);
985
989
  }
986
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug) {
990
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug) {
987
991
  location["params"] = safeguard(location["params"]);
988
992
  }
989
993
  return location;
@@ -1007,7 +1011,7 @@ var Router = {
1007
1011
  );
1008
1012
  }
1009
1013
  silent = 0;
1010
- if (typeof window.__lark_debug !== "undefined" && window.__lark_debug && lastChanged) {
1014
+ if (typeof window.__lark_Debug !== "undefined" && window.__lark_Debug && lastChanged) {
1011
1015
  lastChanged = safeguard(lastChanged);
1012
1016
  }
1013
1017
  return lastChanged;
@@ -1184,7 +1188,7 @@ function parseEventInfo(eventInfo) {
1184
1188
  function findFrameInfo(current, eventType) {
1185
1189
  const eventInfos = [];
1186
1190
  let begin = current;
1187
- const info = current.getAttribute(`v-${eventType}`);
1191
+ const info = current.getAttribute(`@${eventType}`);
1188
1192
  let match;
1189
1193
  if (info) {
1190
1194
  match = parseEventInfo(info);
@@ -1428,7 +1432,7 @@ function vdomGetCompareKey(node) {
1428
1432
  }
1429
1433
  let key = el.autoId ? "" : el.getAttribute("id") || void 0;
1430
1434
  if (!key) {
1431
- key = el.getAttribute(TAG_KEY) || void 0;
1435
+ key = el.getAttribute(LARK_KEYS.DIFF_KEY) || void 0;
1432
1436
  }
1433
1437
  if (!key) {
1434
1438
  const larkView = el.getAttribute(LARK_VIEW);
@@ -1556,17 +1560,17 @@ function vdomSetChildNodes(oldParent, newParent, ref, frame, keys_) {
1556
1560
  }
1557
1561
  }
1558
1562
  function vdomSetNode(oldNode, newNode, oldParent, ref, frame, keys_) {
1559
- if (vdomSpecialDiff(oldNode, newNode) || oldNode.nodeType === 1 && oldNode.hasAttribute(TAG_VIEW_KEY) || !(oldNode.isEqualNode && oldNode.isEqualNode(newNode))) {
1563
+ if (vdomSpecialDiff(oldNode, newNode) || oldNode.nodeType === 1 && oldNode.hasAttribute(LARK_KEYS.VIEW_KEY) || !(oldNode.isEqualNode && oldNode.isEqualNode(newNode))) {
1560
1564
  if (oldNode.nodeType === newNode.nodeType && oldNode.nodeName === newNode.nodeName) {
1561
1565
  if (oldNode.nodeType === 1) {
1562
1566
  const oldEl = oldNode;
1563
1567
  const newEl = newNode;
1564
- const staticKey = newEl.getAttribute(TAG_KEY);
1565
- if (staticKey && staticKey === oldEl.getAttribute(TAG_KEY)) {
1568
+ const staticKey = newEl.getAttribute(LARK_KEYS.DIFF_KEY);
1569
+ if (staticKey && staticKey === oldEl.getAttribute(LARK_KEYS.DIFF_KEY)) {
1566
1570
  return;
1567
1571
  }
1568
1572
  const newLarkView = newEl.getAttribute(LARK_VIEW);
1569
- const updateAttribute = !newEl.getAttribute(TAG_ATTR_KEY) || newEl.getAttribute(TAG_ATTR_KEY) !== oldEl.getAttribute(TAG_ATTR_KEY);
1573
+ const updateAttribute = !newEl.getAttribute(LARK_KEYS.ATTR_KEY) || newEl.getAttribute(LARK_KEYS.ATTR_KEY) !== oldEl.getAttribute(LARK_KEYS.ATTR_KEY);
1570
1574
  let updateChildren = true;
1571
1575
  if (newLarkView) {
1572
1576
  const oldFrameId = oldEl.getAttribute("id") || "";
@@ -1711,7 +1715,7 @@ var Updater = class {
1711
1715
  if (key) {
1712
1716
  result = this.data[key];
1713
1717
  }
1714
- if (typeof window !== "undefined" && window.__lark_debug) {
1718
+ if (typeof window !== "undefined" && window.__lark_Debug) {
1715
1719
  return safeguard(result);
1716
1720
  }
1717
1721
  return result;
@@ -1846,10 +1850,10 @@ var Updater = class {
1846
1850
  // src/view.ts
1847
1851
  var VIEW_GLOBALS = {};
1848
1852
  if (typeof window !== "undefined") {
1849
- VIEW_GLOBALS["win"] = window;
1853
+ VIEW_GLOBALS["window"] = window;
1850
1854
  }
1851
1855
  if (typeof document !== "undefined") {
1852
- VIEW_GLOBALS["doc"] = document;
1856
+ VIEW_GLOBALS["document"] = document;
1853
1857
  }
1854
1858
  function viewPrepare(oView) {
1855
1859
  if (oView.ctors) {
@@ -1976,7 +1980,7 @@ function viewMergeMixins(mixins, viewClass, ctors) {
1976
1980
  if (!has(node, p)) continue;
1977
1981
  const fn = node[p];
1978
1982
  const exist = temp[p];
1979
- if (p === "ctor") {
1983
+ if (p === "make") {
1980
1984
  ctors.push(fn);
1981
1985
  continue;
1982
1986
  }
@@ -2313,23 +2317,23 @@ var View = class _View {
2313
2317
  * Extend View to create a new View subclass.
2314
2318
  *
2315
2319
  * Supports:
2316
- * - props.ctor: constructor-like init (called with initParams + {node, deep})
2320
+ * - props.make: constructor-like init (called with initParams + {node, deep})
2317
2321
  * - props.mixins: array of mixin objects
2318
2322
  * - Event method patterns: `'name<click>'` etc.
2319
2323
  */
2320
2324
  static extend(props, statics) {
2321
2325
  props = props || {};
2322
- const ctor = props["ctor"];
2326
+ const make = props["make"];
2323
2327
  const ctors = [];
2324
- if (ctor) {
2325
- ctors.push(ctor);
2328
+ if (make) {
2329
+ ctors.push(make);
2326
2330
  }
2327
2331
  const ParentView = this;
2328
2332
  const ChildView = class extends ParentView {
2329
2333
  constructor(nodeId, ownerFrame, initParams, node, mixinCtors) {
2330
2334
  super(nodeId, ownerFrame, initParams, node, []);
2331
2335
  for (const key in props) {
2332
- if (has(props, key) && key !== "ctor") {
2336
+ if (has(props, key) && key !== "make") {
2333
2337
  this[key] = props[key];
2334
2338
  }
2335
2339
  }
@@ -2351,7 +2355,7 @@ var View = class _View {
2351
2355
  };
2352
2356
  const proto = ChildView.prototype;
2353
2357
  for (const key in props) {
2354
- if (has(props, key) && key !== "ctor") {
2358
+ if (has(props, key) && key !== "make") {
2355
2359
  proto[key] = props[key];
2356
2360
  }
2357
2361
  }
@@ -2430,7 +2434,7 @@ var Frame = class _Frame extends EventEmitter {
2430
2434
  hasAltered = 0;
2431
2435
  /** Whether view is destroyed */
2432
2436
  destroyed = 0;
2433
- /** View path (lark-view attribute value) */
2437
+ /** View path (v-lark attribute value) */
2434
2438
  viewPath;
2435
2439
  /** Original template before mount */
2436
2440
  originalTemplate;
@@ -3157,6 +3161,114 @@ function serviceSend(service, attrs, done, flag, save) {
3157
3161
  }
3158
3162
  }
3159
3163
 
3164
+ // src/frame-visualizer/index.ts
3165
+ var MSG_PING = "LARK_VIS_PING";
3166
+ var MSG_PONG = "LARK_VIS_PONG";
3167
+ var MSG_REQUEST_TREE = "LARK_VIS_REQUEST_TREE";
3168
+ var MSG_TREE = "LARK_VIS_TREE";
3169
+ var MSG_TREE_DELTA = "LARK_VIS_TREE_DELTA";
3170
+ function serializeView(view) {
3171
+ return {
3172
+ id: view.id,
3173
+ rendered: !!view.rendered,
3174
+ signature: view.signature,
3175
+ observedStateKeys: view.observedStateKeys ?? null,
3176
+ locationObserved: {
3177
+ flag: view.locationObserved.flag,
3178
+ keys: view.locationObserved.keys,
3179
+ observePath: view.locationObserved.observePath
3180
+ },
3181
+ hasTemplate: !!view.template
3182
+ };
3183
+ }
3184
+ function serializeFrame(frameId) {
3185
+ const frame = Frame.get(frameId);
3186
+ if (!frame) return null;
3187
+ const view = frame.view;
3188
+ const children = [];
3189
+ for (const childId of frame.children()) {
3190
+ const childNode = serializeFrame(childId);
3191
+ if (childNode) {
3192
+ children.push(childNode);
3193
+ }
3194
+ }
3195
+ return {
3196
+ id: frame.id,
3197
+ parentId: frame.parentId ?? null,
3198
+ viewPath: frame.viewPath ?? null,
3199
+ childrenCount: frame.childrenCount,
3200
+ readyCount: frame.readyCount,
3201
+ childrenCreated: frame.childrenCreated,
3202
+ childrenAlter: frame.childrenAlter,
3203
+ destroyed: frame.destroyed,
3204
+ view: view ? serializeView(view) : null,
3205
+ children
3206
+ };
3207
+ }
3208
+ function serializeFrameTree() {
3209
+ const root = Frame.root();
3210
+ const rootNode = serializeFrame(root.id);
3211
+ let totalFrames = 0;
3212
+ const countFrames = (node) => {
3213
+ if (!node) return;
3214
+ totalFrames++;
3215
+ for (const child of node.children) {
3216
+ countFrames(child);
3217
+ }
3218
+ };
3219
+ countFrames(rootNode);
3220
+ return {
3221
+ root: rootNode,
3222
+ totalFrames,
3223
+ timestamp: Date.now(),
3224
+ rootId: root.id
3225
+ };
3226
+ }
3227
+ var bridgeInstalled = false;
3228
+ var lastTreeJson = "";
3229
+ function installFrameVisualizerBridge() {
3230
+ if (bridgeInstalled) return;
3231
+ if (typeof window === "undefined") return;
3232
+ bridgeInstalled = true;
3233
+ window.addEventListener("message", (event) => {
3234
+ const data = event.data;
3235
+ if (!data || typeof data !== "object") return;
3236
+ const type = data.type;
3237
+ if (type === MSG_PING) {
3238
+ const source = event.source;
3239
+ if (source) {
3240
+ source.postMessage({ type: MSG_PONG }, { targetOrigin: "*" });
3241
+ }
3242
+ return;
3243
+ }
3244
+ if (type === MSG_REQUEST_TREE) {
3245
+ const tree = serializeFrameTree();
3246
+ const source = event.source;
3247
+ if (source) {
3248
+ source.postMessage(
3249
+ { type: MSG_TREE, data: tree },
3250
+ { targetOrigin: "*" }
3251
+ );
3252
+ }
3253
+ }
3254
+ });
3255
+ Frame.on("add", () => {
3256
+ pushTreeUpdate();
3257
+ });
3258
+ Frame.on("remove", () => {
3259
+ pushTreeUpdate();
3260
+ });
3261
+ }
3262
+ function pushTreeUpdate() {
3263
+ if (window === window.parent) return;
3264
+ const tree = serializeFrameTree();
3265
+ const treeJson = JSON.stringify(tree);
3266
+ if (treeJson !== lastTreeJson) {
3267
+ lastTreeJson = treeJson;
3268
+ window.parent.postMessage({ type: MSG_TREE_DELTA, data: tree }, "*");
3269
+ }
3270
+ }
3271
+
3160
3272
  // src/framework.ts
3161
3273
  var config = {
3162
3274
  rootId: "lark-root",
@@ -3363,6 +3475,7 @@ var Framework = {
3363
3475
  booted3 = true;
3364
3476
  markBooted();
3365
3477
  markRouterBooted();
3478
+ installFrameVisualizerBridge();
3366
3479
  const rootFrame2 = Frame.root(config.rootId);
3367
3480
  Router._bind();
3368
3481
  const defaultView = config.defaultView || "";
@@ -3795,20 +3908,20 @@ function createState(initialData, config2) {
3795
3908
  lazySet(state, initialData);
3796
3909
  return state;
3797
3910
  }
3798
- var currLazySetKey = null;
3911
+ var curLazySetKey = null;
3799
3912
  function lazySet(target, data) {
3800
3913
  if (isObject(data)) {
3801
3914
  Reflect.ownKeys(data).forEach((key) => {
3802
3915
  const strKey = key;
3803
- if (currLazySetKey) throw new Error("[lark-store] lazy set key conflict");
3804
- currLazySetKey = strKey;
3916
+ if (curLazySetKey) throw new Error("[lark-store] lazy set key conflict");
3917
+ curLazySetKey = strKey;
3805
3918
  target[strKey] = data[strKey];
3806
3919
  });
3807
3920
  }
3808
3921
  }
3809
3922
  function isLazySet(property) {
3810
- if (currLazySetKey === property) {
3811
- currLazySetKey = "";
3923
+ if (curLazySetKey === property) {
3924
+ curLazySetKey = "";
3812
3925
  return true;
3813
3926
  }
3814
3927
  return false;
@@ -4302,7 +4415,7 @@ function multi(useStore) {
4302
4415
  return useFn(view);
4303
4416
  });
4304
4417
  const mixinObj = {
4305
- ctor() {
4418
+ make() {
4306
4419
  if (!rootViewPath) {
4307
4420
  const owner = this["owner"];
4308
4421
  rootViewPath = owner?.["path"] || "";
@@ -4352,17 +4465,17 @@ function restoreComments(source, comments) {
4352
4465
  }
4353
4466
  function processViewEvents(source) {
4354
4467
  return source.replace(
4355
- /v-(\w+)="([^"]+)"/g,
4468
+ /@(\w+)="([^"]+)"/g,
4356
4469
  (fullAttr, eventName, attrValue) => {
4357
4470
  const eventMatch = attrValue.match(/^(\w+)\((.*)\)$/s);
4358
4471
  if (!eventMatch) return fullAttr;
4359
4472
  const handlerName = eventMatch[1];
4360
4473
  const paramsStr = eventMatch[2].trim();
4361
4474
  if (!paramsStr) {
4362
- return `v-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4475
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}()"`;
4363
4476
  }
4364
4477
  const urlParams = jsObjectToUrlParams(paramsStr);
4365
- return `v-${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4478
+ return `@${eventName}="${VIEW_ID_PLACEHOLDER}${SPLITTER2}${handlerName}(${urlParams})"`;
4366
4479
  }
4367
4480
  );
4368
4481
  }
@@ -4588,12 +4701,12 @@ function convertArtExpression(code, debug, lineNo, blockStack = []) {
4588
4701
  const last = blockStack.pop();
4589
4702
  if (!last) {
4590
4703
  throw new Error(
4591
- `[@lark/mvc error(template] unexpected {{${code}}}: no matching open block`
4704
+ `[@lark/mvc error] unexpected {{${code}}}: no matching open block`
4592
4705
  );
4593
4706
  }
4594
4707
  if (last.ctrl !== expectedCtrl) {
4595
4708
  throw new Error(
4596
- `[@lark/mvc error(template] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4709
+ `[@lark/mvc error] unexpected {{${code}}}: expected {{/${last.ctrl}}} to close block opened at line ${last.line}`
4597
4710
  );
4598
4711
  }
4599
4712
  return `${debugPrefix}<%}%>`;
@@ -4953,19 +5066,18 @@ var BUILTIN_GLOBALS = {
4953
5066
  // Reference lookup: (refData, value) => key
4954
5067
  // Finds or allocates a SPLITTER-prefixed key in refData for a given
4955
5068
  // object reference. Used by {{@ref}} operator for passing object
4956
- // references to child views via lark-view attributes.
4957
- // Aligned with mx.js Updater_Ref.
5069
+ // references to child views via v-lark attributes.
4958
5070
  $i: 1,
4959
5071
  // URI encoder: v => encodeURIComponent($n(v)).replace(/[!')(*]/g, extraMap)
4960
5072
  // Extends encodeURIComponent with encoding of ! ' ( ) *.
4961
- // Applied to values in v-event URL parameters and {{!uri}} contexts.
5073
+ // Applied to values in @event URL parameters and {{!uri}} contexts.
4962
5074
  $eu: 1,
4963
5075
  // Quote encoder: v => $n(v).replace(/['"\\]/g, '\\$&')
4964
5076
  // Escapes quotes and backslashes for safe embedding in HTML attribute
4965
5077
  // values (e.g. data-json='...').
4966
5078
  $eq: 1,
4967
5079
  // View ID — the unique identifier of the owning View instance.
4968
- // Injected into v-event attribute values at render time so that
5080
+ // Injected into @event attribute values at render time so that
4969
5081
  // EventDelegator can dispatch events to the correct View handler.
4970
5082
  // The \x1f placeholder in compiled output is replaced with '+$viewId+'.
4971
5083
  $viewId: 1,
@@ -5068,10 +5180,7 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5068
5180
  SPLITTER,
5069
5181
  Service,
5070
5182
  State,
5071
- TAG_ATTR_KEY,
5072
- TAG_KEY,
5073
5183
  TAG_NAME_REGEXP,
5074
- TAG_VIEW_KEY,
5075
5184
  Updater,
5076
5185
  VIEW_EVENT_METHOD_REGEXP,
5077
5186
  View,
@@ -5102,6 +5211,7 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5102
5211
  getStore,
5103
5212
  getUseStore,
5104
5213
  has,
5214
+ installFrameVisualizerBridge,
5105
5215
  isArray,
5106
5216
  isPlainObject,
5107
5217
  isPrimitive,
@@ -5122,6 +5232,7 @@ var BUILTIN_GLOBAL_SET = new Set(Object.keys(BUILTIN_GLOBALS));
5122
5232
  parseUri,
5123
5233
  registerViewClass,
5124
5234
  safeguard,
5235
+ serializeFrameTree,
5125
5236
  setData,
5126
5237
  shallowSet,
5127
5238
  storeMark,
package/dist/index.d.cts CHANGED
@@ -417,7 +417,7 @@ type Constructable = new (...args: never[]) => unknown;
417
417
  * This is the only place where we touch constructor internals -
418
418
  * it's a low-level framework utility for View.extend.
419
419
  */
420
- declare function classExtend<Proto extends object, Statics extends object>(ctor: Constructable, base: Constructable, props: Proto, statics: Statics): void;
420
+ declare function classExtend<Proto extends object, Statics extends object>(make: Constructable, base: Constructable, props: Proto, statics: Statics): void;
421
421
 
422
422
  /** Internal splitter character (invisible, used as namespace separator) */
423
423
  declare const SPLITTER = "\u001E";
@@ -426,14 +426,8 @@ declare const ROUTER_EVENTS: {
426
426
  CHANGED: string;
427
427
  PAGE_UNLOAD: string;
428
428
  };
429
- /** Attribute name: lark-key (static key for skipping VDOM diff) */
430
- declare const TAG_KEY = "lark-key";
431
- /** Attribute name: lark-attr-key (static attribute key) */
432
- declare const TAG_ATTR_KEY = "lark-attr-key";
433
- /** Attribute name: l (view key for assign) */
434
- declare const TAG_VIEW_KEY = "lark-view-key";
435
- /** Attribute name: lark-view */
436
- declare const LARK_VIEW = "lark-view";
429
+ /** Attribute name: v-lark */
430
+ declare const LARK_VIEW = "v-lark";
437
431
  /** View event method regex: e.g. "app\x1eclickHandler(click)" or "clickHandler()"
438
432
  * Group 1: optional frame ID (before SPLITTER)
439
433
  * Group 2: handler name
@@ -492,7 +486,7 @@ declare function unmark$1(host: object): void;
492
486
  */
493
487
  /**
494
488
  * Wrap data with a Proxy for debug-mode protection.
495
- * Only active when window.__lark_debug is true and Proxy is available.
489
+ * Only active when window.__lark_Debug is true and Proxy is available.
496
490
  *
497
491
  * @param data - Data to wrap
498
492
  * @param getter - Optional callback when properties are read
@@ -608,7 +602,7 @@ declare const State: {
608
602
  digest(data?: Record<string, unknown>, excludes?: Set<string>): void;
609
603
  diff(): Readonly<Record<string, number>>;
610
604
  clean(keys: string): {
611
- ctor: AnyFunc;
605
+ make: AnyFunc;
612
606
  };
613
607
  on(event: string, handler: AnyFunc): typeof State;
614
608
  off(event: string, handler?: AnyFunc): typeof State;
@@ -749,7 +743,7 @@ declare class View {
749
743
  * Extend View to create a new View subclass.
750
744
  *
751
745
  * Supports:
752
- * - props.ctor: constructor-like init (called with initParams + {node, deep})
746
+ * - props.make: constructor-like init (called with initParams + {node, deep})
753
747
  * - props.mixins: array of mixin objects
754
748
  * - Event method patterns: `'name<click>'` etc.
755
749
  */
@@ -791,7 +785,7 @@ declare class Frame extends EventEmitter implements FrameLike {
791
785
  hasAltered: number;
792
786
  /** Whether view is destroyed */
793
787
  destroyed: number;
794
- /** View path (lark-view attribute value) */
788
+ /** View path (v-lark attribute value) */
795
789
  viewPath?: string;
796
790
  /** Original template before mount */
797
791
  originalTemplate?: string;
@@ -884,7 +878,7 @@ declare function vdomUnmountFrames(frame: FrameLike, node: ChildNode): void;
884
878
  declare function vdomGetNode(html: string, refNode: Element): Element;
885
879
  /**
886
880
  * Get compare key for a DOM node (for keyed diff).
887
- * Uses id, lark-key (static key), or lark-view path.
881
+ * Uses id, ldk (static key), or v-lark path.
888
882
  */
889
883
  declare function vdomGetCompareKey(node: ChildNode): string | undefined;
890
884
  /**
@@ -1233,7 +1227,7 @@ declare const Framework: {
1233
1227
  digest(data?: Record<string, unknown>, excludes?: Set<string>): void;
1234
1228
  diff(): Readonly<Record<string, number>>;
1235
1229
  clean(keys: string): {
1236
- ctor: AnyFunc;
1230
+ make: AnyFunc;
1237
1231
  };
1238
1232
  on(event: string, handler: AnyFunc): typeof State;
1239
1233
  off(event: string, handler?: AnyFunc): typeof State;
@@ -1392,19 +1386,85 @@ declare function isStoreActive(name: string): boolean;
1392
1386
  declare function cell<T = unknown>(data: T): T;
1393
1387
  declare function observeCell(state: ProxyObject, cb: AnyFunc, immediate?: boolean): () => void;
1394
1388
  declare function multi<S = Record<string, unknown>>(useStore: LarkUseStore<S>): [LarkUseStore<S>, {
1395
- ctor: AnyFunc;
1389
+ make: AnyFunc;
1396
1390
  }];
1397
1391
 
1392
+ /** Serialized view info attached to a frame node */
1393
+ interface SerializedViewInfo {
1394
+ /** View ID (same as frame ID) */
1395
+ id: string;
1396
+ /** Whether the view has rendered at least once */
1397
+ rendered: boolean;
1398
+ /** View signature (> 0 = active) */
1399
+ signature: number;
1400
+ /** Observed state keys */
1401
+ observedStateKeys: string[] | null;
1402
+ /** Location observation config */
1403
+ locationObserved: {
1404
+ flag: number;
1405
+ keys: string[];
1406
+ observePath: boolean;
1407
+ };
1408
+ /** Whether view has a template function */
1409
+ hasTemplate: boolean;
1410
+ }
1411
+ /** A single node in the serialized frame tree */
1412
+ interface SerializedFrameNode {
1413
+ /** Frame ID (same as owner DOM element ID) */
1414
+ id: string;
1415
+ /** Parent frame ID (null for root) */
1416
+ parentId: string | null;
1417
+ /** View path (v-lark attribute value) */
1418
+ viewPath: string | null;
1419
+ /** Number of child frames */
1420
+ childrenCount: number;
1421
+ /** Number of children that have fired 'created' */
1422
+ readyCount: number;
1423
+ /** Whether children have been created */
1424
+ childrenCreated: number;
1425
+ /** Whether children are in alter state */
1426
+ childrenAlter: number;
1427
+ /** Whether this frame is destroyed */
1428
+ destroyed: number;
1429
+ /** Serialized view info (null if no view mounted) */
1430
+ view: SerializedViewInfo | null;
1431
+ /** Child frame nodes */
1432
+ children: SerializedFrameNode[];
1433
+ }
1434
+ /** Top-level serialized frame tree */
1435
+ interface SerializedFrameTree {
1436
+ /** Root frame node */
1437
+ root: SerializedFrameNode | null;
1438
+ /** Total frame count */
1439
+ totalFrames: number;
1440
+ /** Timestamp of serialization */
1441
+ timestamp: number;
1442
+ /** Root element ID */
1443
+ rootId: string;
1444
+ }
1445
+ /**
1446
+ * Serialize the entire Frame tree starting from root.
1447
+ */
1448
+ declare function serializeFrameTree(): SerializedFrameTree;
1449
+ /**
1450
+ * Install the Frame Visualizer Bridge.
1451
+ * Listens for postMessage events from the visualizer and responds
1452
+ * with serialized frame tree data.
1453
+ *
1454
+ * This should be called once during Framework.boot().
1455
+ */
1456
+ declare function installFrameVisualizerBridge(): void;
1457
+
1398
1458
  /**
1399
1459
  * @lark/framework Template Compiler
1400
1460
  *
1401
1461
  * convertArtSyntax() ({{}} → <% %>)
1402
- * processViewEvents() (v-event prefix + param encoding)
1462
+ * processViewEvents() (@event prefix + param encoding)
1403
1463
  * compileToFunction() (<% %> → JS template function)
1404
1464
  * extractGlobalVars() (AST-based global var analysis via @babel/parser)
1405
1465
  *
1406
1466
  * - All template operators: = (escape), ! (raw), @ (ref lookup), : (binding)
1407
- * - v-event attribute processing with $g prefix + \x1e separator
1467
+ * - @event attribute processing with $g prefix + \x1e separator
1408
1468
  * - $n (null-safe toString), $e (HTML entity encode), $eu (URI encode), $eq (quote encode), $i (ref lookup)
1409
1469
  * - Debug mode with line tracking ($expr/$art/$line) and try-catch error wrapper
1410
1470
  * - View ID injection (\x1f → '+$viewId+')
@@ -1468,4 +1528,4 @@ declare function compileTemplate(source: string, options?: CompileOptions): stri
1468
1528
  */
1469
1529
  declare function extractGlobalVars(source: string): string[];
1470
1530
 
1471
- export { type AnyFunc, Bag, type BagEntry, CALL_BREAK_TIME, Cache, type CacheEntry, type CacheOptions, type CompileOptions, type Constructable, EVENT_METHOD_REGEXP, EventDelegator, EventEmitter, type EventListenerEntry, Frame, type FrameBoundElement, type FrameChildrenMap, type FrameInvokeEntry, type FrameLike, type FrameReadyMap, Framework, type FrameworkConfig, LARK_VIEW, type LarkUseStore, type Location, type LocationDiff, type MixinEventHandler, type NodeUseStore, type ObservePayload, type ParamDiff, type ParsedUri, type PendingCacheEntry, Platform, ROUTER_EVENTS, type ReactUseStore, type RouteViewConfig, Router, SPLITTER, Service, type ServiceCacheInfo, type ServiceConstructor, type ServiceEntry, type ServiceMetaEntry, type ServiceOptions, State, type StoreConfig, type StoreMethods, TAG_ATTR_KEY, TAG_KEY, TAG_NAME_REGEXP, TAG_VIEW_KEY, Updater, type UpdaterLike, type VDomOp, type VDomRef, VIEW_EVENT_METHOD_REGEXP, type VdomElement, View, type ViewClassInternal, type ViewEventObjectMap, type ViewEventSelectorEntry, type ViewEventSelectorMap, type ViewGlobalEventEntry, type ViewInstance, type ViewLocationObserved, type ViewResourceEntry, type ViewResourceMap, type VoidFunc, applyIdUpdates, applyStyle, applyVdomOps, assign, cell, classExtend, cloneData, cloneStore, compileTemplate, createState, createVdomRef, defineStore, delStore, encodeHTML, encodeQ, encodeSafe, encodeURIExtra, ensureElementId, extractGlobalVars, funcWithTry, generateId, getAttribute, getById, getPlatform, getStore, getUseStore, has, isArray, isPlainObject, isPrimitive, isPrimitiveOrFunc, isState, isStoreActive, keys, lazySet, mark$1 as mark, markBooted, markRouterBooted, multi, nextCounter, nodeInside, noop, now, observeCell, parseUri, registerViewClass, safeguard, setData, shallowSet, mark as storeMark, unmark as storeUnmark, syncCounter, toMap, toUri, translateData, unmark$1 as unmark, vdomGetCompareKey, vdomGetNode, vdomSetAttributes, vdomSetChildNodes, vdomSetNode, vdomSpecialDiff, vdomUnmountFrames };
1531
+ export { type AnyFunc, Bag, type BagEntry, CALL_BREAK_TIME, Cache, type CacheEntry, type CacheOptions, type CompileOptions, type Constructable, EVENT_METHOD_REGEXP, EventDelegator, EventEmitter, type EventListenerEntry, Frame, type FrameBoundElement, type FrameChildrenMap, type FrameInvokeEntry, type FrameLike, type FrameReadyMap, Framework, type FrameworkConfig, LARK_VIEW, type LarkUseStore, type Location, type LocationDiff, type MixinEventHandler, type NodeUseStore, type ObservePayload, type ParamDiff, type ParsedUri, type PendingCacheEntry, Platform, ROUTER_EVENTS, type ReactUseStore, type RouteViewConfig, Router, SPLITTER, type SerializedFrameNode, type SerializedFrameTree, type SerializedViewInfo, Service, type ServiceCacheInfo, type ServiceConstructor, type ServiceEntry, type ServiceMetaEntry, type ServiceOptions, State, type StoreConfig, type StoreMethods, TAG_NAME_REGEXP, Updater, type UpdaterLike, type VDomOp, type VDomRef, VIEW_EVENT_METHOD_REGEXP, type VdomElement, View, type ViewClassInternal, type ViewEventObjectMap, type ViewEventSelectorEntry, type ViewEventSelectorMap, type ViewGlobalEventEntry, type ViewInstance, type ViewLocationObserved, type ViewResourceEntry, type ViewResourceMap, type VoidFunc, applyIdUpdates, applyStyle, applyVdomOps, assign, cell, classExtend, cloneData, cloneStore, compileTemplate, createState, createVdomRef, defineStore, delStore, encodeHTML, encodeQ, encodeSafe, encodeURIExtra, ensureElementId, extractGlobalVars, funcWithTry, generateId, getAttribute, getById, getPlatform, getStore, getUseStore, has, installFrameVisualizerBridge, isArray, isPlainObject, isPrimitive, isPrimitiveOrFunc, isState, isStoreActive, keys, lazySet, mark$1 as mark, markBooted, markRouterBooted, multi, nextCounter, nodeInside, noop, now, observeCell, parseUri, registerViewClass, safeguard, serializeFrameTree, setData, shallowSet, mark as storeMark, unmark as storeUnmark, syncCounter, toMap, toUri, translateData, unmark$1 as unmark, vdomGetCompareKey, vdomGetNode, vdomSetAttributes, vdomSetChildNodes, vdomSetNode, vdomSpecialDiff, vdomUnmountFrames };