@lark.js/mvc 0.0.9 → 0.0.10

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
@@ -1,4 +1,4 @@
1
- // src/constants.ts
1
+ // src/common.ts
2
2
  var globalCounter = 0;
3
3
  var SPLITTER = String.fromCharCode(30);
4
4
  var RouterEvents = {
@@ -14,6 +14,7 @@ var VIEW_EVENT_METHOD_REGEXP = /^(\$?)([\w]*)<(.*?)>(?:<([\w ,]*)>)?$/;
14
14
  var URL_TRIM_HASH_REGEXP = /(?:^.*\/\/[^/]+|#.*$)/gi;
15
15
  var URL_TRIM_QUERY_REGEXP = /^[^#]*#?!?/;
16
16
  var URL_PARAM_REGEXP = /([^=&?/#]+)=?([^&#?]*)/g;
17
+ var IS_URL_PARAMS = /(?!^)=|&/;
17
18
  var URL_QUERY_HASH_REGEXP = /[#?].*$/;
18
19
  var SVG_NS = "http://www.w3.org/2000/svg";
19
20
  var MATH_NS = "http://www.w3.org/1998/Math/MathML";
@@ -22,13 +23,66 @@ var CALL_BREAK_TIME = 48;
22
23
  function nextCounter() {
23
24
  return ++globalCounter;
24
25
  }
26
+ var HTML_ENT_MAP = {
27
+ "&": "amp",
28
+ "<": "lt",
29
+ ">": "gt",
30
+ '"': "#34",
31
+ "'": "#39",
32
+ "`": "#96"
33
+ };
34
+ var HTML_ENT_REGEXP = /[&<>"'`]/g;
35
+ function encodeSafe(v) {
36
+ return String(v == null ? "" : v);
37
+ }
38
+ function encodeHTML(v) {
39
+ return String(v == null ? "" : v).replace(
40
+ HTML_ENT_REGEXP,
41
+ (m) => "&" + HTML_ENT_MAP[m] + ";"
42
+ );
43
+ }
44
+ var URI_ENT_MAP = {
45
+ "!": "%21",
46
+ "'": "%27",
47
+ "(": "%28",
48
+ ")": "%29",
49
+ "*": "%2A"
50
+ };
51
+ var URI_ENT_REGEXP = /[!')(*]/g;
52
+ function encodeURIExtra(v) {
53
+ return encodeURIComponent(encodeSafe(v)).replace(
54
+ URI_ENT_REGEXP,
55
+ (m) => URI_ENT_MAP[m]
56
+ );
57
+ }
58
+ var QUOTE_ENT_REGEXP = /['"\\]/g;
59
+ function encodeQ(v) {
60
+ return encodeSafe(v).replace(QUOTE_ENT_REGEXP, "\\$&");
61
+ }
62
+ function refFn(ref, value, key) {
63
+ const counter = ref[SPLITTER];
64
+ for (let i = counter; --i; ) {
65
+ key = SPLITTER + i;
66
+ if (ref[key] === value) return key;
67
+ }
68
+ key = SPLITTER + ref[SPLITTER]++;
69
+ ref[key] = value;
70
+ return key;
71
+ }
72
+ function isRefToken(s) {
73
+ if (s.length < 2 || s[0] !== SPLITTER) return false;
74
+ for (let i = 1; i < s.length; i++) {
75
+ const c = s.charCodeAt(i);
76
+ if (c < "0".charCodeAt(0) || c > "9".charCodeAt(0)) return false;
77
+ }
78
+ return true;
79
+ }
25
80
 
26
81
  // src/utils.ts
27
82
  function isPlainObject(value) {
28
83
  if (typeof value !== "object" || value === null) return false;
29
84
  const proto = Object.getPrototypeOf(value);
30
- if (proto === null) return true;
31
- return proto === Object.prototype || proto === null;
85
+ return proto === null || proto === Object.prototype;
32
86
  }
33
87
  function isPrimitiveOrFunc(value) {
34
88
  return !value || typeof value !== "object" && typeof value !== "function";
@@ -40,9 +94,6 @@ var _localCounter = 0;
40
94
  function generateId(prefix) {
41
95
  return (prefix || "lark_") + _localCounter++;
42
96
  }
43
- function syncCounter(val) {
44
- _localCounter = val;
45
- }
46
97
  function noop() {
47
98
  }
48
99
  function hasOwnProperty(owner, prop) {
@@ -97,14 +148,6 @@ function setData(newData, oldData, changedKeys2, excludes) {
97
148
  }
98
149
  return changed;
99
150
  }
100
- function isRefToken(s) {
101
- if (s.length < 2 || s[0] !== SPLITTER) return false;
102
- for (let i = 1; i < s.length; i++) {
103
- const c = s.charCodeAt(i);
104
- if (c < 48 || c > 57) return false;
105
- }
106
- return true;
107
- }
108
151
  function translateData(data, value) {
109
152
  if (isPrimitive(value)) {
110
153
  const prop = String(value);
@@ -133,11 +176,11 @@ function getById(id) {
133
176
  function getAttribute(element, attr) {
134
177
  return Element.prototype.getAttribute.call(element, attr) ?? "";
135
178
  }
136
- function ensureElementId(element) {
179
+ function ensureElementId(element, prefix) {
137
180
  const id = element.getAttribute("id");
138
181
  if (id) return id;
139
182
  element.autoId = 1;
140
- const newId = generateId();
183
+ const newId = generateId(prefix);
141
184
  element.id = newId;
142
185
  return newId;
143
186
  }
@@ -167,11 +210,6 @@ function parseUri(uri) {
167
210
  });
168
211
  return { path: actualPath, params };
169
212
  }
170
- var IS_URL_PARAMS = {
171
- test(s) {
172
- return /(?!^)=|&/.test(s);
173
- }
174
- };
175
213
  function toUri(path, params, keepEmpty) {
176
214
  const pairs = [];
177
215
  let hasParams = false;
@@ -199,7 +237,7 @@ function toMap(list, key) {
199
237
  return map;
200
238
  }
201
239
  function now() {
202
- return Date.now ? Date.now() : (/* @__PURE__ */ new Date()).getTime();
240
+ return Date.now();
203
241
  }
204
242
 
205
243
  // src/apply-style.ts
@@ -838,14 +876,12 @@ function getChanged(oldLoc, newLoc) {
838
876
  setDiff("path", oldLoc["path"], newLoc["path"]);
839
877
  if (changedParams["path"]) {
840
878
  result["path"] = changedParams["path"];
841
- hasChanged = true;
842
879
  result.changed = true;
843
880
  }
844
881
  const viewKey = "view";
845
882
  setDiff(viewKey, oldLoc.view, newLoc.view);
846
883
  if (changedParams[viewKey]) {
847
884
  result.view = changedParams[viewKey];
848
- hasChanged = true;
849
885
  result.changed = true;
850
886
  }
851
887
  const finalResult = {
@@ -1627,57 +1663,8 @@ function applyIdUpdates(updates) {
1627
1663
  }
1628
1664
  }
1629
1665
  }
1630
- var EncoderMap = {
1631
- "&": "amp",
1632
- "<": "lt",
1633
- ">": "gt",
1634
- '"': "#34",
1635
- "'": "#39",
1636
- "`": "#96"
1637
- };
1638
- var ENCODE_REGEXP = /[&<>"'`]/g;
1639
- function encodeHTML(v) {
1640
- return String(v == null ? "" : v).replace(
1641
- ENCODE_REGEXP,
1642
- (m) => "&" + EncoderMap[m] + ";"
1643
- );
1644
- }
1645
- function encodeSafe(v) {
1646
- return String(v == null ? "" : v);
1647
- }
1648
- var URIMap = {
1649
- "!": "%21",
1650
- "'": "%27",
1651
- "(": "%28",
1652
- ")": "%29",
1653
- "*": "%2A"
1654
- };
1655
- var URI_ENCODE_REGEXP = /[!')(*]/g;
1656
- function encodeURIExtra(v) {
1657
- return encodeURIComponent(encodeSafe(v)).replace(
1658
- URI_ENCODE_REGEXP,
1659
- (m) => URIMap[m]
1660
- );
1661
- }
1662
- var QUOTE_REGEXP = /['"\\]/g;
1663
- function encodeQ(v) {
1664
- return encodeSafe(v).replace(QUOTE_REGEXP, "\\$&");
1665
- }
1666
1666
 
1667
1667
  // src/updater.ts
1668
- function updaterRef(refDataIn, value, key) {
1669
- const refData = refDataIn;
1670
- const counter = refData[SPLITTER];
1671
- for (let i = counter; --i; ) {
1672
- key = SPLITTER + i;
1673
- if (refData[key] === value) {
1674
- return key;
1675
- }
1676
- }
1677
- key = SPLITTER + refData[SPLITTER]++;
1678
- refData[key] = value;
1679
- return key;
1680
- }
1681
1668
  var Updater = class {
1682
1669
  /** View ID (same as owner frame ID) */
1683
1670
  viewId;
@@ -1785,7 +1772,7 @@ var Updater = class {
1785
1772
  encodeHTML,
1786
1773
  encodeSafe,
1787
1774
  encodeURIExtra,
1788
- updaterRef,
1775
+ refFn,
1789
1776
  encodeQ
1790
1777
  );
1791
1778
  const newDom = domGetNode(html, node);
@@ -1833,17 +1820,12 @@ var Updater = class {
1833
1820
  * Translate a refData reference back to its original value.
1834
1821
  *
1835
1822
  * The ref protocol is `SPLITTER` + ascii decimal digits — the exact format
1836
- * emitted by `updaterRef`. We require that exact shape so a user-supplied
1823
+ * emitted by `refFn`. We require that exact shape so a user-supplied
1837
1824
  * string that merely begins with SPLITTER is never accidentally resolved
1838
1825
  * (or mishandled as a "missing ref").
1839
1826
  */
1840
1827
  translate(data) {
1841
- if (typeof data !== "string") return data;
1842
- if (data.length < 2 || data[0] !== SPLITTER) return data;
1843
- for (let i = 1; i < data.length; i++) {
1844
- const c = data.charCodeAt(i);
1845
- if (c < 48 || c > 57) return data;
1846
- }
1828
+ if (typeof data !== "string" || !isRefToken(data)) return data;
1847
1829
  return hasOwnProperty(this.refData, data) ? this.refData[data] : data;
1848
1830
  }
1849
1831
  /**
@@ -1910,8 +1892,6 @@ var View = class _View {
1910
1892
  observedStateKeys;
1911
1893
  /** Resource map */
1912
1894
  resources = {};
1913
- /** Assign method reference */
1914
- assignMethod;
1915
1895
  /** Whether endUpdate pending */
1916
1896
  endUpdatePending;
1917
1897
  /** Internal event storage */
@@ -1988,7 +1968,7 @@ var View = class _View {
1988
1968
  */
1989
1969
  beginUpdate(id) {
1990
1970
  if (this.signature > 0 && this.endUpdatePending !== void 0) {
1991
- this.ownerFrame.unmountZone(id, true);
1971
+ this.ownerFrame.unmountZone(id);
1992
1972
  }
1993
1973
  }
1994
1974
  /**
@@ -2007,7 +1987,7 @@ var View = class _View {
2007
1987
  this.rendered = true;
2008
1988
  }
2009
1989
  const ownerFrame = this.ownerFrame;
2010
- ownerFrame.mountZone(updateId, inner);
1990
+ ownerFrame.mountZone(updateId);
2011
1991
  if (!flag) {
2012
1992
  setTimeout(
2013
1993
  this.wrapAsync(() => {
@@ -2232,7 +2212,6 @@ var View = class _View {
2232
2212
  proto["$evtObjMap"] = eventsObject;
2233
2213
  proto["$globalEvtList"] = eventsList;
2234
2214
  proto["$selMap"] = selectorObject;
2235
- proto["$assignFn"] = proto["assign"];
2236
2215
  return makes;
2237
2216
  }
2238
2217
  /**
@@ -2746,7 +2725,7 @@ var Frame = class _Frame extends EventEmitter {
2746
2725
  /**
2747
2726
  * Unmount a child frame.
2748
2727
  */
2749
- unmountFrame(id, _inner) {
2728
+ unmountFrame(id) {
2750
2729
  const targetId = id ? this.childrenMap[id] : this.id;
2751
2730
  const frame = frameRegistry.get(targetId);
2752
2731
  if (!frame) return;
@@ -2768,7 +2747,7 @@ var Frame = class _Frame extends EventEmitter {
2768
2747
  /**
2769
2748
  * Mount all views in a zone.
2770
2749
  */
2771
- mountZone(zoneId, _inner) {
2750
+ mountZone(zoneId) {
2772
2751
  const targetZone = zoneId || this.id;
2773
2752
  this.holdFireCreated = 1;
2774
2753
  const rootEl = document.getElementById(targetZone);
@@ -2778,7 +2757,7 @@ var Frame = class _Frame extends EventEmitter {
2778
2757
  viewElements.forEach((el) => {
2779
2758
  if (!(el instanceof HTMLElement)) return;
2780
2759
  if (htmlElIsBound(el)) return;
2781
- const elId = ensureElementId2(el);
2760
+ const elId = ensureElementId(el, "frame_");
2782
2761
  el.frameBound = 1;
2783
2762
  const viewPath = getAttribute(el, LARK_VIEW);
2784
2763
  frames.push([elId, viewPath]);
@@ -2792,7 +2771,7 @@ var Frame = class _Frame extends EventEmitter {
2792
2771
  /**
2793
2772
  * Unmount all views in a zone.
2794
2773
  */
2795
- unmountZone(zoneId, _inner) {
2774
+ unmountZone(zoneId) {
2796
2775
  for (const childId in this.childrenMap) {
2797
2776
  if (hasOwnProperty(this.childrenMap, childId)) {
2798
2777
  if (!zoneId || childId !== zoneId) {
@@ -2921,17 +2900,6 @@ var Frame = class _Frame extends EventEmitter {
2921
2900
  }
2922
2901
  return rootFrame;
2923
2902
  }
2924
- /**
2925
- * @deprecated Use `Frame.getRoot()` for read-only access or
2926
- * `Frame.createRoot(id)` to create the root explicitly. The single-method
2927
- * `root()` blurred the distinction and was a common source of bugs in
2928
- * Micro-Frontend hosts.
2929
- *
2930
- * Kept for backward compatibility — behavior unchanged.
2931
- */
2932
- static root(rootId) {
2933
- return _Frame.createRoot(rootId);
2934
- }
2935
2903
  /** Bind event listener (static) */
2936
2904
  static on(event, handler) {
2937
2905
  staticEmitter.on(event, handler);
@@ -2950,14 +2918,6 @@ var Frame = class _Frame extends EventEmitter {
2950
2918
  function htmlElIsBound(element) {
2951
2919
  return !!element.frameBound;
2952
2920
  }
2953
- function ensureElementId2(element) {
2954
- const id = element.getAttribute("id");
2955
- if (id) return id;
2956
- element.autoId = 1;
2957
- const newId = generateId("frame_");
2958
- element.id = newId;
2959
- return newId;
2960
- }
2961
2921
  function removeFrame(id, wasCreated) {
2962
2922
  const frameInstance = frameRegistry.get(id);
2963
2923
  if (!frameInstance) return;
@@ -4138,18 +4098,14 @@ function create(name, creator) {
4138
4098
  changedKeys2.add(key);
4139
4099
  }
4140
4100
  }
4141
- let recomputed = false;
4142
4101
  for (const [key, def] of computedDefs) {
4143
4102
  if (def.deps.some((dep) => changedKeys2.has(dep))) {
4144
4103
  const newVal = def.fn();
4145
4104
  if (!Object.is(state[key], newVal)) {
4146
4105
  state[key] = newVal;
4147
- recomputed = true;
4148
4106
  }
4149
4107
  }
4150
4108
  }
4151
- if (recomputed) {
4152
- }
4153
4109
  };
4154
4110
  const subscribe = (listener) => {
4155
4111
  listeners.add(listener);
@@ -4214,7 +4170,6 @@ function bindStore(view, store, selector) {
4214
4170
  view.on("destroy", off);
4215
4171
  return off;
4216
4172
  }
4217
- var defineStore = create;
4218
4173
  export {
4219
4174
  CALL_BREAK_TIME,
4220
4175
  Cache,
@@ -4236,58 +4191,23 @@ export {
4236
4191
  Updater,
4237
4192
  VIEW_EVENT_METHOD_REGEXP,
4238
4193
  View,
4239
- applyDomOps,
4240
- applyIdUpdates,
4241
4194
  applyStyle,
4242
- assign,
4243
4195
  bindStore,
4244
4196
  computed,
4245
4197
  create,
4246
- createDomRef,
4247
- defineStore,
4248
4198
  defineView,
4249
- domGetCompareKey,
4250
- domGetNode,
4251
- domSetAttributes,
4252
- domSetChildNodes,
4253
- domSetNode,
4254
- domSpecialDiff,
4255
- domUnmountFrames,
4256
- encodeHTML,
4257
- encodeQ,
4258
- encodeSafe,
4259
- encodeURIExtra,
4260
- ensureElementId,
4261
4199
  config as frameworkConfig,
4262
- funcWithTry,
4263
- generateId,
4264
- getAttribute,
4265
- getById,
4266
4200
  getRouteMode,
4267
- hasOwnProperty,
4268
4201
  installFrameVisualizerBridge,
4269
4202
  invalidateViewClass,
4270
- isPlainObject,
4271
- isPrimitive,
4272
- isPrimitiveOrFunc,
4273
- keys,
4274
4203
  mark,
4275
4204
  markBooted,
4276
4205
  markRouterBooted,
4277
4206
  nextCounter,
4278
- nodeInside,
4279
- noop,
4280
- now,
4281
- parseUri,
4282
4207
  registerViewClass,
4283
4208
  resetProjectsMap,
4284
4209
  safeguard,
4285
4210
  serializeFrameTree,
4286
- setData,
4287
- syncCounter,
4288
- toMap,
4289
- toUri,
4290
- translateData,
4291
4211
  unmark,
4292
4212
  use,
4293
4213
  useUrlState
package/dist/runtime.cjs CHANGED
@@ -27,6 +27,12 @@ __export(runtime_exports, {
27
27
  strSafe: () => strSafe
28
28
  });
29
29
  module.exports = __toCommonJS(runtime_exports);
30
+
31
+ // src/common.ts
32
+ var SPLITTER = String.fromCharCode(30);
33
+ var EVENT_METHOD_REGEXP = new RegExp(
34
+ `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
35
+ );
30
36
  var HTML_ENT_MAP = {
31
37
  "&": "amp",
32
38
  "<": "lt",
@@ -35,9 +41,16 @@ var HTML_ENT_MAP = {
35
41
  "'": "#39",
36
42
  "`": "#96"
37
43
  };
38
- var HTML_ENT_REGEXP = /[&<>"`']/g;
39
- var strSafe = (v) => "" + (v == null ? "" : v);
40
- var encHtml = (v) => strSafe(v).replace(HTML_ENT_REGEXP, (m) => "&" + HTML_ENT_MAP[m] + ";");
44
+ var HTML_ENT_REGEXP = /[&<>"'`]/g;
45
+ function encodeSafe(v) {
46
+ return String(v == null ? "" : v);
47
+ }
48
+ function encodeHTML(v) {
49
+ return String(v == null ? "" : v).replace(
50
+ HTML_ENT_REGEXP,
51
+ (m) => "&" + HTML_ENT_MAP[m] + ";"
52
+ );
53
+ }
41
54
  var URI_ENT_MAP = {
42
55
  "!": "%21",
43
56
  "'": "%27",
@@ -46,11 +59,17 @@ var URI_ENT_MAP = {
46
59
  "*": "%2A"
47
60
  };
48
61
  var URI_ENT_REGEXP = /[!')(*]/g;
49
- var encUri = (v) => encodeURIComponent(strSafe(v)).replace(URI_ENT_REGEXP, (m) => URI_ENT_MAP[m]);
50
- var QUOTE_REGEXP = /['"\\]/g;
51
- var encQuote = (v) => strSafe(v).replace(QUOTE_REGEXP, "\\$&");
52
- var refFn = (ref, value, key) => {
53
- const SPLITTER = String.fromCharCode(30);
62
+ function encodeURIExtra(v) {
63
+ return encodeURIComponent(encodeSafe(v)).replace(
64
+ URI_ENT_REGEXP,
65
+ (m) => URI_ENT_MAP[m]
66
+ );
67
+ }
68
+ var QUOTE_ENT_REGEXP = /['"\\]/g;
69
+ function encodeQ(v) {
70
+ return encodeSafe(v).replace(QUOTE_ENT_REGEXP, "\\$&");
71
+ }
72
+ function refFn(ref, value, key) {
54
73
  const counter = ref[SPLITTER];
55
74
  for (let i = counter; --i; ) {
56
75
  key = SPLITTER + i;
@@ -59,7 +78,13 @@ var refFn = (ref, value, key) => {
59
78
  key = SPLITTER + ref[SPLITTER]++;
60
79
  ref[key] = value;
61
80
  return key;
62
- };
81
+ }
82
+
83
+ // src/runtime.ts
84
+ var strSafe = encodeSafe;
85
+ var encHtml = encodeHTML;
86
+ var encUri = encodeURIExtra;
87
+ var encQuote = encodeQ;
63
88
  // Annotate the CommonJS export names for ESM import in node:
64
89
  0 && (module.exports = {
65
90
  encHtml,
@@ -1,3 +1,17 @@
1
+ /** Null-safe String conversion */
2
+ declare function encodeSafe(v: unknown): string;
3
+ /** HTML entity encoding for safe output */
4
+ declare function encodeHTML(v: unknown): string;
5
+ /** URI-encode with extra character encoding */
6
+ declare function encodeURIExtra(v: unknown): string;
7
+ /** Quote-encode for attribute values */
8
+ declare function encodeQ(v: unknown): string;
9
+ /**
10
+ * Template reference function for creating stable keys for objects.
11
+ * Stores objects in refData with SPLITTER-prefixed keys.
12
+ */
13
+ declare function refFn(ref: Record<string, unknown>, value: unknown, key: string): string;
14
+
1
15
  /**
2
16
  * Template runtime helpers.
3
17
  *
@@ -7,23 +21,18 @@
7
21
  *
8
22
  * The helpers below are aliased to `$strSafe / $encHtml / $encUri / $encQuote /
9
23
  * $refFn` inside the IIFE that the compiler produces — see `compiler.ts`.
24
+ *
25
+ * Canonical implementations live in `./common` so that dom.ts, runtime.ts,
26
+ * and updater.ts all share a single copy.
10
27
  */
28
+
11
29
  /** Null-safe `String(value)` — `null`/`undefined` become `""`. */
12
- declare const strSafe: (v: unknown) => string;
30
+ declare const strSafe: typeof encodeSafe;
13
31
  /** HTML-escape a value for safe embedding in markup. */
14
- declare const encHtml: (v: unknown) => string;
32
+ declare const encHtml: typeof encodeHTML;
15
33
  /** Percent-encode a value, with extra characters escaped for stricter URIs. */
16
- declare const encUri: (v: unknown) => string;
34
+ declare const encUri: typeof encodeURIExtra;
17
35
  /** Backslash-escape quotes and backslashes for attribute string contents. */
18
- declare const encQuote: (v: unknown) => string;
19
- /**
20
- * Look up (or assign) a stable refData token for an object value.
21
- *
22
- * Templates use `{{@expr}}` to pass live JS values (objects/functions) through
23
- * the DOM by writing the token into an attribute, then resolving it back to
24
- * the original value when the event fires. `refData[SPLITTER]` holds the
25
- * monotonic counter; `refData[SPLITTER + n]` holds the slot.
26
- */
27
- declare const refFn: (ref: Record<string, unknown>, value: unknown, key: string) => string;
36
+ declare const encQuote: typeof encodeQ;
28
37
 
29
38
  export { encHtml, encQuote, encUri, refFn, strSafe };
package/dist/runtime.d.ts CHANGED
@@ -1,3 +1,17 @@
1
+ /** Null-safe String conversion */
2
+ declare function encodeSafe(v: unknown): string;
3
+ /** HTML entity encoding for safe output */
4
+ declare function encodeHTML(v: unknown): string;
5
+ /** URI-encode with extra character encoding */
6
+ declare function encodeURIExtra(v: unknown): string;
7
+ /** Quote-encode for attribute values */
8
+ declare function encodeQ(v: unknown): string;
9
+ /**
10
+ * Template reference function for creating stable keys for objects.
11
+ * Stores objects in refData with SPLITTER-prefixed keys.
12
+ */
13
+ declare function refFn(ref: Record<string, unknown>, value: unknown, key: string): string;
14
+
1
15
  /**
2
16
  * Template runtime helpers.
3
17
  *
@@ -7,23 +21,18 @@
7
21
  *
8
22
  * The helpers below are aliased to `$strSafe / $encHtml / $encUri / $encQuote /
9
23
  * $refFn` inside the IIFE that the compiler produces — see `compiler.ts`.
24
+ *
25
+ * Canonical implementations live in `./common` so that dom.ts, runtime.ts,
26
+ * and updater.ts all share a single copy.
10
27
  */
28
+
11
29
  /** Null-safe `String(value)` — `null`/`undefined` become `""`. */
12
- declare const strSafe: (v: unknown) => string;
30
+ declare const strSafe: typeof encodeSafe;
13
31
  /** HTML-escape a value for safe embedding in markup. */
14
- declare const encHtml: (v: unknown) => string;
32
+ declare const encHtml: typeof encodeHTML;
15
33
  /** Percent-encode a value, with extra characters escaped for stricter URIs. */
16
- declare const encUri: (v: unknown) => string;
34
+ declare const encUri: typeof encodeURIExtra;
17
35
  /** Backslash-escape quotes and backslashes for attribute string contents. */
18
- declare const encQuote: (v: unknown) => string;
19
- /**
20
- * Look up (or assign) a stable refData token for an object value.
21
- *
22
- * Templates use `{{@expr}}` to pass live JS values (objects/functions) through
23
- * the DOM by writing the token into an attribute, then resolving it back to
24
- * the original value when the event fires. `refData[SPLITTER]` holds the
25
- * monotonic counter; `refData[SPLITTER + n]` holds the slot.
26
- */
27
- declare const refFn: (ref: Record<string, unknown>, value: unknown, key: string) => string;
36
+ declare const encQuote: typeof encodeQ;
28
37
 
29
38
  export { encHtml, encQuote, encUri, refFn, strSafe };
package/dist/runtime.js CHANGED
@@ -1,4 +1,8 @@
1
- // src/runtime.ts
1
+ // src/common.ts
2
+ var SPLITTER = String.fromCharCode(30);
3
+ var EVENT_METHOD_REGEXP = new RegExp(
4
+ `(?:([\\w-]+)${SPLITTER})?([^(]+)\\(([\\s\\S]*?)?\\)`
5
+ );
2
6
  var HTML_ENT_MAP = {
3
7
  "&": "amp",
4
8
  "<": "lt",
@@ -7,9 +11,16 @@ var HTML_ENT_MAP = {
7
11
  "'": "#39",
8
12
  "`": "#96"
9
13
  };
10
- var HTML_ENT_REGEXP = /[&<>"`']/g;
11
- var strSafe = (v) => "" + (v == null ? "" : v);
12
- var encHtml = (v) => strSafe(v).replace(HTML_ENT_REGEXP, (m) => "&" + HTML_ENT_MAP[m] + ";");
14
+ var HTML_ENT_REGEXP = /[&<>"'`]/g;
15
+ function encodeSafe(v) {
16
+ return String(v == null ? "" : v);
17
+ }
18
+ function encodeHTML(v) {
19
+ return String(v == null ? "" : v).replace(
20
+ HTML_ENT_REGEXP,
21
+ (m) => "&" + HTML_ENT_MAP[m] + ";"
22
+ );
23
+ }
13
24
  var URI_ENT_MAP = {
14
25
  "!": "%21",
15
26
  "'": "%27",
@@ -18,11 +29,17 @@ var URI_ENT_MAP = {
18
29
  "*": "%2A"
19
30
  };
20
31
  var URI_ENT_REGEXP = /[!')(*]/g;
21
- var encUri = (v) => encodeURIComponent(strSafe(v)).replace(URI_ENT_REGEXP, (m) => URI_ENT_MAP[m]);
22
- var QUOTE_REGEXP = /['"\\]/g;
23
- var encQuote = (v) => strSafe(v).replace(QUOTE_REGEXP, "\\$&");
24
- var refFn = (ref, value, key) => {
25
- const SPLITTER = String.fromCharCode(30);
32
+ function encodeURIExtra(v) {
33
+ return encodeURIComponent(encodeSafe(v)).replace(
34
+ URI_ENT_REGEXP,
35
+ (m) => URI_ENT_MAP[m]
36
+ );
37
+ }
38
+ var QUOTE_ENT_REGEXP = /['"\\]/g;
39
+ function encodeQ(v) {
40
+ return encodeSafe(v).replace(QUOTE_ENT_REGEXP, "\\$&");
41
+ }
42
+ function refFn(ref, value, key) {
26
43
  const counter = ref[SPLITTER];
27
44
  for (let i = counter; --i; ) {
28
45
  key = SPLITTER + i;
@@ -31,7 +48,13 @@ var refFn = (ref, value, key) => {
31
48
  key = SPLITTER + ref[SPLITTER]++;
32
49
  ref[key] = value;
33
50
  return key;
34
- };
51
+ }
52
+
53
+ // src/runtime.ts
54
+ var strSafe = encodeSafe;
55
+ var encHtml = encodeHTML;
56
+ var encUri = encodeURIExtra;
57
+ var encQuote = encodeQ;
35
58
  export {
36
59
  encHtml,
37
60
  encQuote,