sigmx 0.1.1 → 0.2.0

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.
Files changed (165) hide show
  1. package/README.md +10 -10
  2. package/dist/kernel/compile.d.ts +8 -9
  3. package/dist/kernel/compile.js +102 -67
  4. package/dist/kernel/compile.js.map +2 -2
  5. package/dist/kernel/contracts.d.ts +11 -5
  6. package/dist/kernel/index.d.ts +2 -2
  7. package/dist/kernel/index.js +5 -6
  8. package/dist/kernel/index.js.map +2 -2
  9. package/dist/kernel/precompile.d.ts +8 -10
  10. package/dist/kernel/precompile.js +25 -75
  11. package/dist/kernel/precompile.js.map +2 -2
  12. package/dist/kernel/precompiled.d.ts +7 -4
  13. package/dist/kernel/precompiled.js +5 -5
  14. package/dist/kernel/precompiled.js.map +2 -2
  15. package/dist/kernel/reactive.d.ts +8 -2
  16. package/dist/kernel/reactive.js +91 -62
  17. package/dist/kernel/reactive.js.map +3 -3
  18. package/dist/kernel/runtime.js +78 -68
  19. package/dist/kernel/runtime.js.map +3 -3
  20. package/dist/kernel/scan.d.ts +1 -1
  21. package/dist/kernel/scan.js +3 -3
  22. package/dist/kernel/scan.js.map +2 -2
  23. package/dist/kernel/state.d.ts +4 -3
  24. package/dist/kernel/state.js +91 -80
  25. package/dist/kernel/state.js.map +2 -2
  26. package/dist/kernel/strict-csp.d.ts +0 -5
  27. package/dist/kernel/strict-csp.js +2 -2
  28. package/dist/kernel/strict-csp.js.map +2 -2
  29. package/dist/lib/casing.d.ts +4 -1
  30. package/dist/lib/casing.js +8 -1
  31. package/dist/lib/casing.js.map +2 -2
  32. package/dist/lib/objects.d.ts +5 -3
  33. package/dist/lib/objects.js +10 -5
  34. package/dist/lib/objects.js.map +2 -2
  35. package/dist/lib/schedule.d.ts +3 -3
  36. package/dist/lib/schedule.js +12 -10
  37. package/dist/lib/schedule.js.map +2 -2
  38. package/dist/lib/sse.d.ts +10 -0
  39. package/dist/lib/sse.js +32 -29
  40. package/dist/lib/sse.js.map +2 -2
  41. package/dist/plugins/def.d.ts +5 -0
  42. package/dist/plugins/def.js +22 -0
  43. package/dist/plugins/def.js.map +7 -0
  44. package/dist/plugins/directives/attribute-sync.js +8 -12
  45. package/dist/plugins/directives/attribute-sync.js.map +2 -2
  46. package/dist/plugins/directives/boost.d.ts +1 -1
  47. package/dist/plugins/directives/boost.js +34 -31
  48. package/dist/plugins/directives/boost.js.map +2 -2
  49. package/dist/plugins/directives/busy-flag.js +13 -16
  50. package/dist/plugins/directives/busy-flag.js.map +2 -2
  51. package/dist/plugins/directives/class-toggle.js +17 -16
  52. package/dist/plugins/directives/class-toggle.js.map +2 -2
  53. package/dist/plugins/directives/cloak.js +2 -7
  54. package/dist/plugins/directives/cloak.js.map +2 -2
  55. package/dist/plugins/directives/collapse.js +36 -37
  56. package/dist/plugins/directives/collapse.js.map +2 -2
  57. package/dist/plugins/directives/declare.js +5 -8
  58. package/dist/plugins/directives/declare.js.map +2 -2
  59. package/dist/plugins/directives/derive.js +9 -18
  60. package/dist/plugins/directives/derive.js.map +2 -2
  61. package/dist/plugins/directives/element-ref.js +8 -8
  62. package/dist/plugins/directives/element-ref.js.map +2 -2
  63. package/dist/plugins/directives/event-listener.js +18 -26
  64. package/dist/plugins/directives/event-listener.js.map +2 -2
  65. package/dist/plugins/directives/frame-loop.js +9 -14
  66. package/dist/plugins/directives/frame-loop.js.map +2 -2
  67. package/dist/plugins/directives/html.js +6 -7
  68. package/dist/plugins/directives/html.js.map +2 -2
  69. package/dist/plugins/directives/inline-style.js +17 -20
  70. package/dist/plugins/directives/inline-style.js.map +2 -2
  71. package/dist/plugins/directives/mask.js +19 -23
  72. package/dist/plugins/directives/mask.js.map +2 -2
  73. package/dist/plugins/directives/media-query.d.ts +4 -1
  74. package/dist/plugins/directives/media-query.js +13 -13
  75. package/dist/plugins/directives/media-query.js.map +2 -2
  76. package/dist/plugins/directives/on-mount.js +4 -12
  77. package/dist/plugins/directives/on-mount.js.map +2 -2
  78. package/dist/plugins/directives/patch-listener.js +24 -19
  79. package/dist/plugins/directives/patch-listener.js.map +2 -2
  80. package/dist/plugins/directives/remove-me.js +7 -8
  81. package/dist/plugins/directives/remove-me.js.map +2 -2
  82. package/dist/plugins/directives/scroll-to.d.ts +4 -1
  83. package/dist/plugins/directives/scroll-to.js +8 -14
  84. package/dist/plugins/directives/scroll-to.js.map +2 -2
  85. package/dist/plugins/directives/size-watch.js +7 -12
  86. package/dist/plugins/directives/size-watch.js.map +2 -2
  87. package/dist/plugins/directives/state-dump.js +6 -10
  88. package/dist/plugins/directives/state-dump.js.map +2 -2
  89. package/dist/plugins/directives/storage-sync.js +13 -9
  90. package/dist/plugins/directives/storage-sync.js.map +2 -2
  91. package/dist/plugins/directives/teleport.js +8 -14
  92. package/dist/plugins/directives/teleport.js.map +2 -2
  93. package/dist/plugins/directives/text-content.js +6 -7
  94. package/dist/plugins/directives/text-content.js.map +2 -2
  95. package/dist/plugins/directives/timer.js +7 -13
  96. package/dist/plugins/directives/timer.js.map +2 -2
  97. package/dist/plugins/directives/transition.d.ts +1 -2
  98. package/dist/plugins/directives/transition.js +32 -34
  99. package/dist/plugins/directives/transition.js.map +2 -2
  100. package/dist/plugins/directives/tween.d.ts +2 -2
  101. package/dist/plugins/directives/tween.js +34 -50
  102. package/dist/plugins/directives/tween.js.map +2 -2
  103. package/dist/plugins/directives/two-way-bind.d.ts +1 -1
  104. package/dist/plugins/directives/two-way-bind.js +70 -97
  105. package/dist/plugins/directives/two-way-bind.js.map +2 -2
  106. package/dist/plugins/directives/url-params.js +35 -59
  107. package/dist/plugins/directives/url-params.js.map +3 -3
  108. package/dist/plugins/directives/url-replace.js +6 -7
  109. package/dist/plugins/directives/url-replace.js.map +2 -2
  110. package/dist/plugins/directives/validity.js +6 -9
  111. package/dist/plugins/directives/validity.js.map +2 -2
  112. package/dist/plugins/directives/viewport.js +18 -26
  113. package/dist/plugins/directives/viewport.js.map +2 -2
  114. package/dist/plugins/directives/visibility.js +9 -14
  115. package/dist/plugins/directives/visibility.js.map +2 -2
  116. package/dist/plugins/directives/watch.js +2 -8
  117. package/dist/plugins/directives/watch.js.map +2 -2
  118. package/dist/plugins/functions/bulk-set.js +7 -6
  119. package/dist/plugins/functions/bulk-set.js.map +2 -2
  120. package/dist/plugins/functions/bulk-toggle.js +7 -6
  121. package/dist/plugins/functions/bulk-toggle.js.map +2 -2
  122. package/dist/plugins/functions/confirm.js +2 -2
  123. package/dist/plugins/functions/confirm.js.map +2 -2
  124. package/dist/plugins/functions/copy-text.js +5 -5
  125. package/dist/plugins/functions/copy-text.js.map +2 -2
  126. package/dist/plugins/functions/dispatch.js +5 -5
  127. package/dist/plugins/functions/dispatch.js.map +2 -2
  128. package/dist/plugins/functions/locale-format.d.ts +4 -1
  129. package/dist/plugins/functions/locale-format.js +9 -16
  130. package/dist/plugins/functions/locale-format.js.map +2 -2
  131. package/dist/plugins/functions/range-map.js +6 -6
  132. package/dist/plugins/functions/range-map.js.map +2 -2
  133. package/dist/plugins/functions/request.d.ts +7 -3
  134. package/dist/plugins/functions/request.js +77 -86
  135. package/dist/plugins/functions/request.js.map +2 -2
  136. package/dist/plugins/functions/untracked-read.js +3 -2
  137. package/dist/plugins/functions/untracked-read.js.map +2 -2
  138. package/dist/plugins/functions/websocket.d.ts +3 -3
  139. package/dist/plugins/functions/websocket.js +13 -24
  140. package/dist/plugins/functions/websocket.js.map +2 -2
  141. package/dist/plugins/index.d.ts +0 -2
  142. package/dist/plugins/index.js +0 -4
  143. package/dist/plugins/index.js.map +2 -2
  144. package/dist/plugins/server-events/apply-elements.d.ts +1 -1
  145. package/dist/plugins/server-events/apply-elements.js +41 -43
  146. package/dist/plugins/server-events/apply-elements.js.map +2 -2
  147. package/dist/plugins/server-events/apply-state.js +9 -12
  148. package/dist/plugins/server-events/apply-state.js.map +2 -2
  149. package/dist/plugins/server-events/morph.js +46 -66
  150. package/dist/plugins/server-events/morph.js.map +3 -3
  151. package/dist/presets/all.js +0 -4
  152. package/dist/presets/all.js.map +2 -2
  153. package/dist/server.d.ts +10 -4
  154. package/dist/server.js +42 -14
  155. package/dist/server.js.map +2 -2
  156. package/dist/sigmx.standalone.js +1 -1
  157. package/dist/vite.js +17 -7
  158. package/dist/vite.js.map +2 -2
  159. package/package.json +4 -2
  160. package/dist/plugins/directives/transition-name.d.ts +0 -1
  161. package/dist/plugins/directives/transition-name.js +0 -11
  162. package/dist/plugins/directives/transition-name.js.map +0 -7
  163. package/dist/plugins/directives/trap.d.ts +0 -5
  164. package/dist/plugins/directives/trap.js +0 -54
  165. package/dist/plugins/directives/trap.js.map +0 -7
package/dist/lib/sse.d.ts CHANGED
@@ -4,6 +4,16 @@ export type ServerEvent = {
4
4
  id?: string;
5
5
  retry?: number;
6
6
  };
7
+ type StreamState = {
8
+ id?: string;
9
+ retry?: number;
10
+ };
11
+ /**
12
+ * Parse one blank-line-delimited block of `field: value` lines (the SSE wire format). `id` and
13
+ * `retry` persist in `state` across blocks; comments start with `:`. Undefined without data lines.
14
+ */
15
+ export declare const parseBlock: (block: string, state?: StreamState) => ServerEvent | undefined;
7
16
  export declare const readEvents: (body: ReadableStream<Uint8Array>, onEvent: (e: ServerEvent) => void) => Promise<void>;
8
17
  /** Event payloads: each data line is `key value`; repeated keys join with newlines. */
9
18
  export declare const parseFields: (data: string) => Record<string, string>;
19
+ export {};
package/dist/lib/sse.js CHANGED
@@ -1,42 +1,44 @@
1
- const readEvents = async (body, onEvent) => {
2
- const reader = body.getReader();
3
- const decoder = new TextDecoder();
4
- let buffer = "";
1
+ const parseBlock = (block, state = {}) => {
5
2
  let event = "";
6
- let data = [];
7
- let id;
8
- let retry;
9
- const flush = () => {
10
- if (data.length) onEvent({ event: event || "message", data: data.join("\n"), id, retry });
11
- event = "";
12
- data = [];
13
- };
14
- const line = (l) => {
15
- if (!l) return flush();
16
- if (l[0] === ":") return;
3
+ const data = [];
4
+ for (const l of block.split(/\r?\n/)) {
17
5
  const c = l.indexOf(":");
6
+ if (!c) continue;
18
7
  const field = c < 0 ? l : l.slice(0, c);
19
- let v = c < 0 ? "" : l.slice(c + 1);
20
- if (v[0] === " ") v = v.slice(1);
8
+ const v = (c < 0 ? "" : l.slice(c + 1)).replace(/^ /, "");
21
9
  if (field === "event") event = v;
22
10
  else if (field === "data") data.push(v);
23
- else if (field === "id") id = v;
24
- else if (field === "retry" && /^\d+$/.test(v)) retry = +v;
11
+ else if (field === "id") state.id = v;
12
+ else if (field === "retry" && /^\d+$/.test(v)) state.retry = +v;
13
+ }
14
+ if (data.length) return { event: event || "message", data: data.join("\n"), id: state.id, retry: state.retry };
15
+ };
16
+ const readEvents = async (body, onEvent) => {
17
+ const reader = body.getReader();
18
+ const decoder = new TextDecoder();
19
+ const state = {};
20
+ let buffer = "";
21
+ let scan = 0;
22
+ const dispatch = (block) => {
23
+ const e = parseBlock(block, state);
24
+ if (e) onEvent(e);
25
25
  };
26
26
  for (; ; ) {
27
27
  const { value, done } = await reader.read();
28
- if (done) break;
29
- buffer += decoder.decode(value, { stream: true });
30
- for (; ; ) {
31
- const i = buffer.search(/\r\n|\r|\n/);
32
- if (i < 0) break;
33
- const l = buffer.slice(0, i);
34
- buffer = buffer.slice(i + (buffer[i] === "\r" && buffer[i + 1] === "\n" ? 2 : 1));
35
- line(l);
28
+ buffer += decoder.decode(value, { stream: !done });
29
+ const sep = /\r?\n\r?\n/g;
30
+ sep.lastIndex = scan;
31
+ for (let m = sep.exec(buffer); m; m = sep.exec(buffer)) {
32
+ dispatch(buffer.slice(0, m.index));
33
+ buffer = buffer.slice(m.index + m[0].length);
34
+ sep.lastIndex = 0;
35
+ }
36
+ scan = Math.max(0, buffer.length - 3);
37
+ if (done) {
38
+ dispatch(buffer);
39
+ break;
36
40
  }
37
41
  }
38
- if (buffer) line(buffer);
39
- flush();
40
42
  };
41
43
  const parseFields = (data) => {
42
44
  const out = {};
@@ -50,6 +52,7 @@ ${v}` : v;
50
52
  return out;
51
53
  };
52
54
  export {
55
+ parseBlock,
53
56
  parseFields,
54
57
  readEvents
55
58
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/lib/sse.ts"],
4
- "sourcesContent": ["export type ServerEvent = { event: string; data: string; id?: string; retry?: number };\n\nexport const readEvents = async (\n body: ReadableStream<Uint8Array>,\n onEvent: (e: ServerEvent) => void,\n): Promise<void> => {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let event = '';\n let data: string[] = [];\n let id: string | undefined;\n let retry: number | undefined;\n const flush = () => {\n if (data.length) onEvent({ event: event || 'message', data: data.join('\\n'), id, retry });\n event = '';\n data = [];\n };\n const line = (l: string) => {\n if (!l) return flush();\n if (l[0] === ':') return;\n const c = l.indexOf(':');\n const field = c < 0 ? l : l.slice(0, c);\n let v = c < 0 ? '' : l.slice(c + 1);\n if (v[0] === ' ') v = v.slice(1);\n if (field === 'event') event = v;\n else if (field === 'data') data.push(v);\n else if (field === 'id') id = v;\n else if (field === 'retry' && /^\\d+$/.test(v)) retry = +v;\n };\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n for (;;) {\n const i = buffer.search(/\\r\\n|\\r|\\n/);\n if (i < 0) break;\n const l = buffer.slice(0, i);\n buffer = buffer.slice(i + (buffer[i] === '\\r' && buffer[i + 1] === '\\n' ? 2 : 1));\n line(l);\n }\n }\n if (buffer) line(buffer);\n flush();\n};\n\n/** Event payloads: each data line is `key value`; repeated keys join with newlines. */\nexport const parseFields = (data: string): Record<string, string> => {\n const out: Record<string, string> = {};\n for (const l of data.split('\\n')) {\n const i = l.indexOf(' ');\n const k = i < 0 ? l : l.slice(0, i);\n const v = i < 0 ? '' : l.slice(i + 1);\n out[k] = k in out ? `${out[k]}\\n${v}` : v;\n }\n return out;\n};\n"],
5
- "mappings": "AAEO,MAAM,aAAa,OACxB,MACA,YACkB;AAClB,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,MAAI,OAAiB,CAAC;AACtB,MAAI;AACJ,MAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,QAAI,KAAK,OAAQ,SAAQ,EAAE,OAAO,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI,GAAG,IAAI,MAAM,CAAC;AACxF,YAAQ;AACR,WAAO,CAAC;AAAA,EACV;AACA,QAAM,OAAO,CAAC,MAAc;AAC1B,QAAI,CAAC,EAAG,QAAO,MAAM;AACrB,QAAI,EAAE,CAAC,MAAM,IAAK;AAClB,UAAM,IAAI,EAAE,QAAQ,GAAG;AACvB,UAAM,QAAQ,IAAI,IAAI,IAAI,EAAE,MAAM,GAAG,CAAC;AACtC,QAAI,IAAI,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,CAAC;AAClC,QAAI,EAAE,CAAC,MAAM,IAAK,KAAI,EAAE,MAAM,CAAC;AAC/B,QAAI,UAAU,QAAS,SAAQ;AAAA,aACtB,UAAU,OAAQ,MAAK,KAAK,CAAC;AAAA,aAC7B,UAAU,KAAM,MAAK;AAAA,aACrB,UAAU,WAAW,QAAQ,KAAK,CAAC,EAAG,SAAQ,CAAC;AAAA,EAC1D;AACA,aAAS;AACP,UAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,eAAS;AACP,YAAM,IAAI,OAAO,OAAO,YAAY;AACpC,UAAI,IAAI,EAAG;AACX,YAAM,IAAI,OAAO,MAAM,GAAG,CAAC;AAC3B,eAAS,OAAO,MAAM,KAAK,OAAO,CAAC,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,OAAO,IAAI,EAAE;AAChF,WAAK,CAAC;AAAA,IACR;AAAA,EACF;AACA,MAAI,OAAQ,MAAK,MAAM;AACvB,QAAM;AACR;AAGO,MAAM,cAAc,CAAC,SAAyC;AACnE,QAAM,MAA8B,CAAC;AACrC,aAAW,KAAK,KAAK,MAAM,IAAI,GAAG;AAChC,UAAM,IAAI,EAAE,QAAQ,GAAG;AACvB,UAAM,IAAI,IAAI,IAAI,IAAI,EAAE,MAAM,GAAG,CAAC;AAClC,UAAM,IAAI,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,CAAC;AACpC,QAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,EAAK,CAAC,KAAK;AAAA,EAC1C;AACA,SAAO;AACT;",
4
+ "sourcesContent": ["export type ServerEvent = { event: string; data: string; id?: string; retry?: number };\ntype StreamState = { id?: string; retry?: number };\n\n/**\n * Parse one blank-line-delimited block of `field: value` lines (the SSE wire format). `id` and\n * `retry` persist in `state` across blocks; comments start with `:`. Undefined without data lines.\n */\nexport const parseBlock = (block: string, state: StreamState = {}): ServerEvent | undefined => {\n let event = '';\n const data: string[] = [];\n for (const l of block.split(/\\r?\\n/)) {\n const c = l.indexOf(':');\n if (!c) continue;\n const field = c < 0 ? l : l.slice(0, c);\n const v = (c < 0 ? '' : l.slice(c + 1)).replace(/^ /, '');\n if (field === 'event') event = v;\n else if (field === 'data') data.push(v);\n else if (field === 'id') state.id = v;\n else if (field === 'retry' && /^\\d+$/.test(v)) state.retry = +v;\n }\n if (data.length) return { event: event || 'message', data: data.join('\\n'), id: state.id, retry: state.retry };\n};\n\nexport const readEvents = async (\n body: ReadableStream<Uint8Array>,\n onEvent: (e: ServerEvent) => void,\n): Promise<void> => {\n const reader = body.getReader();\n const decoder = new TextDecoder();\n const state: StreamState = {};\n let buffer = '';\n let scan = 0; // where the next separator search starts: no rescanning of a large partial event\n const dispatch = (block: string) => {\n const e = parseBlock(block, state);\n if (e) onEvent(e);\n };\n for (;;) {\n const { value, done } = await reader.read();\n buffer += decoder.decode(value, { stream: !done });\n const sep = /\\r?\\n\\r?\\n/g;\n sep.lastIndex = scan;\n for (let m = sep.exec(buffer); m; m = sep.exec(buffer)) {\n dispatch(buffer.slice(0, m.index));\n buffer = buffer.slice(m.index + m[0].length);\n sep.lastIndex = 0;\n }\n scan = Math.max(0, buffer.length - 3);\n if (done) {\n dispatch(buffer);\n break;\n }\n }\n};\n\n/** Event payloads: each data line is `key value`; repeated keys join with newlines. */\nexport const parseFields = (data: string): Record<string, string> => {\n const out: Record<string, string> = {};\n for (const l of data.split('\\n')) {\n const i = l.indexOf(' ');\n const k = i < 0 ? l : l.slice(0, i);\n const v = i < 0 ? '' : l.slice(i + 1);\n out[k] = k in out ? `${out[k]}\\n${v}` : v;\n }\n return out;\n};\n"],
5
+ "mappings": "AAOO,MAAM,aAAa,CAAC,OAAe,QAAqB,CAAC,MAA+B;AAC7F,MAAI,QAAQ;AACZ,QAAM,OAAiB,CAAC;AACxB,aAAW,KAAK,MAAM,MAAM,OAAO,GAAG;AACpC,UAAM,IAAI,EAAE,QAAQ,GAAG;AACvB,QAAI,CAAC,EAAG;AACR,UAAM,QAAQ,IAAI,IAAI,IAAI,EAAE,MAAM,GAAG,CAAC;AACtC,UAAM,KAAK,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,CAAC,GAAG,QAAQ,MAAM,EAAE;AACxD,QAAI,UAAU,QAAS,SAAQ;AAAA,aACtB,UAAU,OAAQ,MAAK,KAAK,CAAC;AAAA,aAC7B,UAAU,KAAM,OAAM,KAAK;AAAA,aAC3B,UAAU,WAAW,QAAQ,KAAK,CAAC,EAAG,OAAM,QAAQ,CAAC;AAAA,EAChE;AACA,MAAI,KAAK,OAAQ,QAAO,EAAE,OAAO,SAAS,WAAW,MAAM,KAAK,KAAK,IAAI,GAAG,IAAI,MAAM,IAAI,OAAO,MAAM,MAAM;AAC/G;AAEO,MAAM,aAAa,OACxB,MACA,YACkB;AAClB,QAAM,SAAS,KAAK,UAAU;AAC9B,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,QAAqB,CAAC;AAC5B,MAAI,SAAS;AACb,MAAI,OAAO;AACX,QAAM,WAAW,CAAC,UAAkB;AAClC,UAAM,IAAI,WAAW,OAAO,KAAK;AACjC,QAAI,EAAG,SAAQ,CAAC;AAAA,EAClB;AACA,aAAS;AACP,UAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC;AACjD,UAAM,MAAM;AACZ,QAAI,YAAY;AAChB,aAAS,IAAI,IAAI,KAAK,MAAM,GAAG,GAAG,IAAI,IAAI,KAAK,MAAM,GAAG;AACtD,eAAS,OAAO,MAAM,GAAG,EAAE,KAAK,CAAC;AACjC,eAAS,OAAO,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM;AAC3C,UAAI,YAAY;AAAA,IAClB;AACA,WAAO,KAAK,IAAI,GAAG,OAAO,SAAS,CAAC;AACpC,QAAI,MAAM;AACR,eAAS,MAAM;AACf;AAAA,IACF;AAAA,EACF;AACF;AAGO,MAAM,cAAc,CAAC,SAAyC;AACnE,QAAM,MAA8B,CAAC;AACrC,aAAW,KAAK,KAAK,MAAM,IAAI,GAAG;AAChC,UAAM,IAAI,EAAE,QAAQ,GAAG;AACvB,UAAM,IAAI,IAAI,IAAI,IAAI,EAAE,MAAM,GAAG,CAAC;AAClC,UAAM,IAAI,IAAI,IAAI,KAAK,EAAE,MAAM,IAAI,CAAC;AACpC,QAAI,CAAC,IAAI,KAAK,MAAM,GAAG,IAAI,CAAC,CAAC;AAAA,EAAK,CAAC,KAAK;AAAA,EAC1C;AACA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,5 @@
1
+ import type { ActionPlugin, AttributePlugin, HandlerPlugin } from '../kernel/contracts.js';
2
+ /** Flags: 1 key required, 2 key forbidden, 4 value required, 8 value forbidden, 32 the value is a literal (`__dynamic` opts into an expression). */
3
+ export declare const dir: (name: string, flags: number, mount: AttributePlugin["mount"], args?: string[]) => AttributePlugin;
4
+ export declare const act: (name: string, call: ActionPlugin["call"]) => ActionPlugin;
5
+ export declare const srv: (name: string, handle: HandlerPlugin["handle"]) => HandlerPlugin;
@@ -0,0 +1,22 @@
1
+ const rule = (flags, required, forbidden) => flags & required ? "required" : flags & forbidden ? "forbidden" : void 0;
2
+ const dir = (name, flags, mount, args) => ({
3
+ type: "attribute",
4
+ name,
5
+ key: rule(flags, 1, 2),
6
+ value: rule(flags, 4, 8),
7
+ literal: !!(flags & 32),
8
+ args,
9
+ mount
10
+ });
11
+ const act = (name, call) => ({ type: "action", name, call });
12
+ const srv = (name, handle) => ({
13
+ type: "handler",
14
+ name,
15
+ handle
16
+ });
17
+ export {
18
+ act,
19
+ dir,
20
+ srv
21
+ };
22
+ //# sourceMappingURL=def.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/plugins/def.ts"],
4
+ "sourcesContent": ["// Compact constructors for the built-in plugins. They build the same objects as `attribute()`,\n// `action()` and `handler()` from the kernel; the numeric flags keep the bundle small.\nimport type { ActionPlugin, AttributePlugin, HandlerPlugin } from '../kernel/contracts.js';\n\ntype Rule = 'required' | 'forbidden' | undefined;\nconst rule = (flags: number, required: number, forbidden: number): Rule =>\n flags & required ? 'required' : flags & forbidden ? 'forbidden' : undefined;\n\n/** Flags: 1 key required, 2 key forbidden, 4 value required, 8 value forbidden, 32 the value is a literal (`__dynamic` opts into an expression). */\nexport const dir = (\n name: string,\n flags: number,\n mount: AttributePlugin['mount'],\n args?: string[],\n): AttributePlugin => ({\n type: 'attribute',\n name,\n key: rule(flags, 1, 2),\n value: rule(flags, 4, 8),\n literal: !!(flags & 32),\n args,\n mount,\n});\nexport const act = (name: string, call: ActionPlugin['call']): ActionPlugin => ({ type: 'action', name, call });\nexport const srv = (name: string, handle: HandlerPlugin['handle']): HandlerPlugin => ({\n type: 'handler',\n name,\n handle,\n});\n"],
5
+ "mappings": "AAKA,MAAM,OAAO,CAAC,OAAe,UAAkB,cAC7C,QAAQ,WAAW,aAAa,QAAQ,YAAY,cAAc;AAG7D,MAAM,MAAM,CACjB,MACA,OACA,OACA,UACqB;AAAA,EACrB,MAAM;AAAA,EACN;AAAA,EACA,KAAK,KAAK,OAAO,GAAG,CAAC;AAAA,EACrB,OAAO,KAAK,OAAO,GAAG,CAAC;AAAA,EACvB,SAAS,CAAC,EAAE,QAAQ;AAAA,EACpB;AAAA,EACA;AACF;AACO,MAAM,MAAM,CAAC,MAAc,UAA8C,EAAE,MAAM,UAAU,MAAM,KAAK;AACtG,MAAM,MAAM,CAAC,MAAc,YAAoD;AAAA,EACpF,MAAM;AAAA,EACN;AAAA,EACA;AACF;",
6
+ "names": []
7
+ }
@@ -1,18 +1,14 @@
1
- import { attribute } from "../../kernel/index.js";
1
+ import { dir } from "../def.js";
2
2
  const put = (el, name, v) => {
3
3
  if (v === false || v == null) el.removeAttribute(name);
4
- else el.setAttribute(name, v === true ? "" : typeof v === "object" ? JSON.stringify(v) : String(v));
4
+ else el.setAttribute(name, v === true ? "" : String(v));
5
5
  };
6
- const attr = attribute({
7
- name: "attr",
8
- value: "required",
9
- mount({ el, key, cased, evaluate, effect }) {
10
- effect(() => {
11
- if (key) return put(el, cased("kebab"), evaluate());
12
- const map = evaluate();
13
- for (const k in map) put(el, k, map[k]);
14
- });
15
- }
6
+ const attr = dir("attr", 4, ({ el, key, cased, evaluate, effect }) => {
7
+ effect(() => {
8
+ if (key) return put(el, cased("kebab"), evaluate());
9
+ const map = evaluate();
10
+ for (const k in map) put(el, k, map[k]);
11
+ });
16
12
  });
17
13
  export {
18
14
  attr
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/attribute-sync.ts"],
4
- "sourcesContent": ["import { attribute } from '../../kernel/index.js';\n\nconst put = (el: Element, name: string, v: unknown) => {\n if (v === false || v == null) el.removeAttribute(name);\n else el.setAttribute(name, v === true ? '' : typeof v === 'object' ? JSON.stringify(v) : String(v));\n};\n\n/** `attr:title=\"expr\"` or `attr=\"{ title: expr }\"`. true \u2192 present, false/null \u2192 removed. */\nexport const attr = attribute({\n name: 'attr',\n value: 'required',\n mount({ el, key, cased, evaluate, effect }) {\n effect(() => {\n if (key) return put(el, cased('kebab'), evaluate());\n const map = evaluate();\n for (const k in map) put(el, k, map[k]);\n });\n },\n});\n"],
5
- "mappings": "AAAA,SAAS,iBAAiB;AAE1B,MAAM,MAAM,CAAC,IAAa,MAAc,MAAe;AACrD,MAAI,MAAM,SAAS,KAAK,KAAM,IAAG,gBAAgB,IAAI;AAAA,MAChD,IAAG,aAAa,MAAM,MAAM,OAAO,KAAK,OAAO,MAAM,WAAW,KAAK,UAAU,CAAC,IAAI,OAAO,CAAC,CAAC;AACpG;AAGO,MAAM,OAAO,UAAU;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM,EAAE,IAAI,KAAK,OAAO,UAAU,OAAO,GAAG;AAC1C,WAAO,MAAM;AACX,UAAI,IAAK,QAAO,IAAI,IAAI,MAAM,OAAO,GAAG,SAAS,CAAC;AAClD,YAAM,MAAM,SAAS;AACrB,iBAAW,KAAK,IAAK,KAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,IACxC,CAAC;AAAA,EACH;AACF,CAAC;",
4
+ "sourcesContent": ["import { dir } from '../def.js';\n\nconst put = (el: Element, name: string, v: unknown) => {\n if (v === false || v == null) el.removeAttribute(name);\n else el.setAttribute(name, v === true ? '' : String(v));\n};\n\n/** `attr:title=\"expr\"` or `attr=\"{ title: expr }\"`. true \u2192 present, false/null \u2192 removed. */\nexport const attr = dir('attr', 4, ({ el, key, cased, evaluate, effect }) => {\n effect(() => {\n if (key) return put(el, cased('kebab'), evaluate());\n const map = evaluate();\n for (const k in map) put(el, k, map[k]);\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,WAAW;AAEpB,MAAM,MAAM,CAAC,IAAa,MAAc,MAAe;AACrD,MAAI,MAAM,SAAS,KAAK,KAAM,IAAG,gBAAgB,IAAI;AAAA,MAChD,IAAG,aAAa,MAAM,MAAM,OAAO,KAAK,OAAO,CAAC,CAAC;AACxD;AAGO,MAAM,OAAO,IAAI,QAAQ,GAAG,CAAC,EAAE,IAAI,KAAK,OAAO,UAAU,OAAO,MAAM;AAC3E,SAAO,MAAM;AACX,QAAI,IAAK,QAAO,IAAI,IAAI,MAAM,OAAO,GAAG,SAAS,CAAC;AAClD,UAAM,MAAM,SAAS;AACrB,eAAW,KAAK,IAAK,KAAI,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,EACxC,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Turns same-origin links and forms inside the element into requests whose full-document response
3
3
  * is morphed into the current page, with history entries: `boost` on a container (or `body`).
4
- * Needs `httpGet`, `httpPost` and `applyElements`. `__replace` replaces the history entry instead.
4
+ * Needs `httpGet`, `httpPost` and `applyElements`.
5
5
  */
6
6
  export declare const boost: import("../../kernel/contracts.js").AttributePlugin;
@@ -1,34 +1,37 @@
1
- import { attribute } from "../../kernel/index.js";
2
- const boost = attribute({
3
- name: "boost",
4
- key: "forbidden",
5
- value: "forbidden",
6
- mount({ el, mods, store, runtime, listen, error, cleanup }) {
7
- const ctx = { el, store, runtime, error, cleanup };
8
- const go = (url, method = "get", evt, form) => {
9
- const o = form ? { contentType: "form", selector: void 0, openWhenHidden: true } : { openWhenHidden: true };
10
- const p = runtime.call(method, { ...ctx, el: form ?? el, evt }, [url, o]);
11
- history[mods.has("replace") ? "replaceState" : "pushState"](null, "", url);
12
- Promise.resolve(p).then(() => scrollTo(0, 0));
13
- };
14
- listen(el, "click", (e) => {
15
- const a = e.target.closest("a[href]");
16
- if (!a || e.defaultPrevented || e.button || e.metaKey || e.ctrlKey || e.shiftKey || a.target || a.hasAttribute("download"))
17
- return;
18
- if (a.origin !== location.origin || a.hash && a.pathname === location.pathname) return;
19
- e.preventDefault();
20
- go(a.href, "get", e);
21
- });
22
- listen(el, "submit", (e) => {
23
- const form = e.target;
24
- if (e.defaultPrevented || form.target) return;
25
- const url = new URL(form.action || location.href);
26
- if (url.origin !== location.origin) return;
27
- e.preventDefault();
28
- go(url.href, form.method.toLowerCase() === "post" ? "post" : "get", e, form);
29
- });
30
- listen(window, "popstate", () => runtime.call("get", ctx, [location.href, { openWhenHidden: true }]));
31
- }
1
+ import { dir } from "../def.js";
2
+ const boost = dir("boost", 10, ({ el, store, runtime, listen, error, cleanup, report }) => {
3
+ const ctx = { el, store, runtime, error, cleanup, report };
4
+ let current = location.pathname + location.search;
5
+ const go = (url, method, evt, form) => {
6
+ evt.preventDefault();
7
+ const p = runtime.call(method, { ...ctx, el: form ?? el, evt }, [url.href, { contentType: form && "form" }]);
8
+ Promise.resolve(p).then((r) => {
9
+ const next = new URL(r && (r.redirected || form && method === "get") ? r.url : url.href);
10
+ current = next.pathname + next.search;
11
+ history.pushState(null, "", next.href);
12
+ const target = next.hash && document.querySelector(next.hash);
13
+ target ? target.scrollIntoView() : scrollTo(0, 0);
14
+ }, report);
15
+ };
16
+ listen(el, "click", (e) => {
17
+ const a = e.target.closest("a[href]");
18
+ if (a && !(e.defaultPrevented || e.button || e.metaKey || e.ctrlKey || e.shiftKey || a.target) && !a.hasAttribute("download") && a.origin === location.origin && !(a.hash && a.pathname === location.pathname && a.search === location.search))
19
+ go(new URL(a.href), "get", e);
20
+ });
21
+ listen(el, "submit", (e) => {
22
+ const form = e.target;
23
+ const attr = (name) => e.submitter?.getAttribute(`form${name}`) ?? form.getAttribute(name);
24
+ const method = (attr("method") ?? "get").toLowerCase();
25
+ const url = new URL(attr("action") || location.href, location.href);
26
+ if (!e.defaultPrevented && !form.target && method !== "dialog" && url.origin === location.origin)
27
+ go(url, method === "post" ? "post" : "get", e, form);
28
+ });
29
+ listen(window, "popstate", () => {
30
+ const now = location.pathname + location.search;
31
+ if (now === current) return;
32
+ current = now;
33
+ Promise.resolve(runtime.call("get", ctx, [location.href, {}])).then(void 0, report);
34
+ });
32
35
  });
33
36
  export {
34
37
  boost
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/boost.ts"],
4
- "sourcesContent": ["import { type ActionCtx, attribute } from '../../kernel/index.js';\n\n/**\n * Turns same-origin links and forms inside the element into requests whose full-document response\n * is morphed into the current page, with history entries: `boost` on a container (or `body`).\n * Needs `httpGet`, `httpPost` and `applyElements`. `__replace` replaces the history entry instead.\n */\nexport const boost = attribute({\n name: 'boost',\n key: 'forbidden',\n value: 'forbidden',\n mount({ el, mods, store, runtime, listen, error, cleanup }) {\n const ctx: ActionCtx = { el, store, runtime, error, cleanup };\n const go = (url: string, method = 'get', evt?: Event, form?: HTMLFormElement) => {\n const o = form ? { contentType: 'form', selector: undefined, openWhenHidden: true } : { openWhenHidden: true };\n const p = runtime.call(method, { ...ctx, el: form ?? el, evt }, [url, o]);\n history[mods.has('replace') ? 'replaceState' : 'pushState'](null, '', url);\n Promise.resolve(p).then(() => scrollTo(0, 0));\n };\n listen(el, 'click', (e: MouseEvent) => {\n const a = (e.target as Element).closest('a[href]') as HTMLAnchorElement | null;\n if (\n !a ||\n e.defaultPrevented ||\n e.button ||\n e.metaKey ||\n e.ctrlKey ||\n e.shiftKey ||\n a.target ||\n a.hasAttribute('download')\n )\n return;\n if (a.origin !== location.origin || (a.hash && a.pathname === location.pathname)) return;\n e.preventDefault();\n go(a.href, 'get', e);\n });\n listen(el, 'submit', (e: SubmitEvent) => {\n const form = e.target as HTMLFormElement;\n if (e.defaultPrevented || form.target) return;\n const url = new URL(form.action || location.href);\n if (url.origin !== location.origin) return;\n e.preventDefault();\n go(url.href, form.method.toLowerCase() === 'post' ? 'post' : 'get', e, form);\n });\n listen(window, 'popstate', () => runtime.call('get', ctx, [location.href, { openWhenHidden: true }]));\n },\n});\n"],
5
- "mappings": "AAAA,SAAyB,iBAAiB;AAOnC,MAAM,QAAQ,UAAU;AAAA,EAC7B,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM,EAAE,IAAI,MAAM,OAAO,SAAS,QAAQ,OAAO,QAAQ,GAAG;AAC1D,UAAM,MAAiB,EAAE,IAAI,OAAO,SAAS,OAAO,QAAQ;AAC5D,UAAM,KAAK,CAAC,KAAa,SAAS,OAAO,KAAa,SAA2B;AAC/E,YAAM,IAAI,OAAO,EAAE,aAAa,QAAQ,UAAU,QAAW,gBAAgB,KAAK,IAAI,EAAE,gBAAgB,KAAK;AAC7G,YAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,GAAG,KAAK,IAAI,QAAQ,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;AACxE,cAAQ,KAAK,IAAI,SAAS,IAAI,iBAAiB,WAAW,EAAE,MAAM,IAAI,GAAG;AACzE,cAAQ,QAAQ,CAAC,EAAE,KAAK,MAAM,SAAS,GAAG,CAAC,CAAC;AAAA,IAC9C;AACA,WAAO,IAAI,SAAS,CAAC,MAAkB;AACrC,YAAM,IAAK,EAAE,OAAmB,QAAQ,SAAS;AACjD,UACE,CAAC,KACD,EAAE,oBACF,EAAE,UACF,EAAE,WACF,EAAE,WACF,EAAE,YACF,EAAE,UACF,EAAE,aAAa,UAAU;AAEzB;AACF,UAAI,EAAE,WAAW,SAAS,UAAW,EAAE,QAAQ,EAAE,aAAa,SAAS,SAAW;AAClF,QAAE,eAAe;AACjB,SAAG,EAAE,MAAM,OAAO,CAAC;AAAA,IACrB,CAAC;AACD,WAAO,IAAI,UAAU,CAAC,MAAmB;AACvC,YAAM,OAAO,EAAE;AACf,UAAI,EAAE,oBAAoB,KAAK,OAAQ;AACvC,YAAM,MAAM,IAAI,IAAI,KAAK,UAAU,SAAS,IAAI;AAChD,UAAI,IAAI,WAAW,SAAS,OAAQ;AACpC,QAAE,eAAe;AACjB,SAAG,IAAI,MAAM,KAAK,OAAO,YAAY,MAAM,SAAS,SAAS,OAAO,GAAG,IAAI;AAAA,IAC7E,CAAC;AACD,WAAO,QAAQ,YAAY,MAAM,QAAQ,KAAK,OAAO,KAAK,CAAC,SAAS,MAAM,EAAE,gBAAgB,KAAK,CAAC,CAAC,CAAC;AAAA,EACtG;AACF,CAAC;",
4
+ "sourcesContent": ["import type { ActionCtx } from '../../kernel/index.js';\nimport { dir } from '../def.js';\n\n/**\n * Turns same-origin links and forms inside the element into requests whose full-document response\n * is morphed into the current page, with history entries: `boost` on a container (or `body`).\n * Needs `httpGet`, `httpPost` and `applyElements`.\n */\nexport const boost = dir('boost', 10, ({ el, store, runtime, listen, error, cleanup, report }) => {\n const ctx: ActionCtx = { el, store, runtime, error, cleanup, report };\n let current = location.pathname + location.search;\n const go = (url: URL, method: string, evt: Event, form?: HTMLFormElement) => {\n evt.preventDefault();\n const p = runtime.call(method, { ...ctx, el: form ?? el, evt }, [url.href, { contentType: form && 'form' }]);\n Promise.resolve(p).then((r) => {\n // The address becomes the final URL: redirects are followed, GET forms carry their fields.\n const next = new URL(r && (r.redirected || (form && method === 'get')) ? r.url : url.href);\n current = next.pathname + next.search;\n history.pushState(null, '', next.href);\n const target = next.hash && document.querySelector(next.hash);\n target ? target.scrollIntoView() : scrollTo(0, 0);\n }, report);\n };\n listen(el, 'click', (e: MouseEvent) => {\n const a = (e.target as Element).closest('a[href]') as HTMLAnchorElement | null;\n if (\n a &&\n !(e.defaultPrevented || e.button || e.metaKey || e.ctrlKey || e.shiftKey || a.target) &&\n !a.hasAttribute('download') &&\n a.origin === location.origin &&\n !(a.hash && a.pathname === location.pathname && a.search === location.search)\n )\n go(new URL(a.href), 'get', e);\n });\n listen(el, 'submit', (e: SubmitEvent) => {\n const form = e.target as HTMLFormElement;\n // Attributes, not properties: an <input name=\"action\"> shadows form.action; the submitter may override.\n const attr = (name: string) => e.submitter?.getAttribute(`form${name}`) ?? form.getAttribute(name);\n const method = (attr('method') ?? 'get').toLowerCase();\n const url = new URL(attr('action') || location.href, location.href);\n if (!e.defaultPrevented && !form.target && method !== 'dialog' && url.origin === location.origin)\n go(url, method === 'post' ? 'post' : 'get', e, form);\n });\n listen(window, 'popstate', () => {\n const now = location.pathname + location.search;\n if (now === current) return; // a hash change: nothing to fetch\n current = now;\n Promise.resolve(runtime.call('get', ctx, [location.href, {}])).then(undefined, report);\n });\n});\n"],
5
+ "mappings": "AACA,SAAS,WAAW;AAOb,MAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,EAAE,IAAI,OAAO,SAAS,QAAQ,OAAO,SAAS,OAAO,MAAM;AAChG,QAAM,MAAiB,EAAE,IAAI,OAAO,SAAS,OAAO,SAAS,OAAO;AACpE,MAAI,UAAU,SAAS,WAAW,SAAS;AAC3C,QAAM,KAAK,CAAC,KAAU,QAAgB,KAAY,SAA2B;AAC3E,QAAI,eAAe;AACnB,UAAM,IAAI,QAAQ,KAAK,QAAQ,EAAE,GAAG,KAAK,IAAI,QAAQ,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM,EAAE,aAAa,QAAQ,OAAO,CAAC,CAAC;AAC3G,YAAQ,QAAQ,CAAC,EAAE,KAAK,CAAC,MAAM;AAE7B,YAAM,OAAO,IAAI,IAAI,MAAM,EAAE,cAAe,QAAQ,WAAW,SAAU,EAAE,MAAM,IAAI,IAAI;AACzF,gBAAU,KAAK,WAAW,KAAK;AAC/B,cAAQ,UAAU,MAAM,IAAI,KAAK,IAAI;AACrC,YAAM,SAAS,KAAK,QAAQ,SAAS,cAAc,KAAK,IAAI;AAC5D,eAAS,OAAO,eAAe,IAAI,SAAS,GAAG,CAAC;AAAA,IAClD,GAAG,MAAM;AAAA,EACX;AACA,SAAO,IAAI,SAAS,CAAC,MAAkB;AACrC,UAAM,IAAK,EAAE,OAAmB,QAAQ,SAAS;AACjD,QACE,KACA,EAAE,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,WAC9E,CAAC,EAAE,aAAa,UAAU,KAC1B,EAAE,WAAW,SAAS,UACtB,EAAE,EAAE,QAAQ,EAAE,aAAa,SAAS,YAAY,EAAE,WAAW,SAAS;AAEtE,SAAG,IAAI,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;AAAA,EAChC,CAAC;AACD,SAAO,IAAI,UAAU,CAAC,MAAmB;AACvC,UAAM,OAAO,EAAE;AAEf,UAAM,OAAO,CAAC,SAAiB,EAAE,WAAW,aAAa,OAAO,IAAI,EAAE,KAAK,KAAK,aAAa,IAAI;AACjG,UAAM,UAAU,KAAK,QAAQ,KAAK,OAAO,YAAY;AACrD,UAAM,MAAM,IAAI,IAAI,KAAK,QAAQ,KAAK,SAAS,MAAM,SAAS,IAAI;AAClE,QAAI,CAAC,EAAE,oBAAoB,CAAC,KAAK,UAAU,WAAW,YAAY,IAAI,WAAW,SAAS;AACxF,SAAG,KAAK,WAAW,SAAS,SAAS,OAAO,GAAG,IAAI;AAAA,EACvD,CAAC;AACD,SAAO,QAAQ,YAAY,MAAM;AAC/B,UAAM,MAAM,SAAS,WAAW,SAAS;AACzC,QAAI,QAAQ,QAAS;AACrB,cAAU;AACV,YAAQ,QAAQ,QAAQ,KAAK,OAAO,KAAK,CAAC,SAAS,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAW,MAAM;AAAA,EACvF,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,19 +1,16 @@
1
- import { attribute } from "../../kernel/index.js";
2
- const indicator = attribute({
3
- name: "indicator",
4
- mount({ el, key, value, cased, store, listen }) {
5
- const path = key ? cased() : value.trim();
6
- const mine = /* @__PURE__ */ new Set();
7
- store.set(path, false);
8
- listen(document, "sigmx-fetch", (e) => {
9
- const { el: from, type, rid } = e.detail;
10
- if (type === "started" && (from === el || el.contains(from))) mine.add(rid);
11
- else if (type === "finished") mine.delete(rid);
12
- else return;
13
- store.set(path, mine.size > 0);
14
- });
15
- return () => store.set(path, false);
16
- }
1
+ import { dir } from "../def.js";
2
+ const indicator = dir("indicator", 0, ({ el, key, value, cased, store, listen }) => {
3
+ const path = key ? cased() : value.trim();
4
+ const mine = /* @__PURE__ */ new Set();
5
+ store.set(path, false);
6
+ listen(document, "sigmx-fetch", (e) => {
7
+ const { el: from, type, rid } = e.detail;
8
+ if (type === "started" && el.contains(from)) mine.add(rid);
9
+ else if (type === "finished") mine.delete(rid);
10
+ else return;
11
+ store.set(path, mine.size > 0);
12
+ });
13
+ return () => store.set(path, false);
17
14
  });
18
15
  export {
19
16
  indicator
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/busy-flag.ts"],
4
- "sourcesContent": ["import { attribute } from '../../kernel/index.js';\n\n/** A boolean signal that is true while a request started from this element (or one inside it) is in flight. */\nexport const indicator = attribute({\n name: 'indicator',\n mount({ el, key, value, cased, store, listen }) {\n const path = key ? cased() : value.trim();\n // Requests are remembered by id at `started`, because the element that made one may have been\n // morphed away by the time it finishes.\n const mine = new Set<number>();\n store.set(path, false);\n listen(document, 'sigmx-fetch', (e: CustomEvent<{ el: Element; type: string; rid: number }>) => {\n const { el: from, type, rid } = e.detail;\n if (type === 'started' && (from === el || el.contains(from))) mine.add(rid);\n else if (type === 'finished') mine.delete(rid);\n else return;\n store.set(path, mine.size > 0);\n });\n return () => store.set(path, false);\n },\n});\n"],
5
- "mappings": "AAAA,SAAS,iBAAiB;AAGnB,MAAM,YAAY,UAAU;AAAA,EACjC,MAAM;AAAA,EACN,MAAM,EAAE,IAAI,KAAK,OAAO,OAAO,OAAO,OAAO,GAAG;AAC9C,UAAM,OAAO,MAAM,MAAM,IAAI,MAAM,KAAK;AAGxC,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,IAAI,MAAM,KAAK;AACrB,WAAO,UAAU,eAAe,CAAC,MAA+D;AAC9F,YAAM,EAAE,IAAI,MAAM,MAAM,IAAI,IAAI,EAAE;AAClC,UAAI,SAAS,cAAc,SAAS,MAAM,GAAG,SAAS,IAAI,GAAI,MAAK,IAAI,GAAG;AAAA,eACjE,SAAS,WAAY,MAAK,OAAO,GAAG;AAAA,UACxC;AACL,YAAM,IAAI,MAAM,KAAK,OAAO,CAAC;AAAA,IAC/B,CAAC;AACD,WAAO,MAAM,MAAM,IAAI,MAAM,KAAK;AAAA,EACpC;AACF,CAAC;",
4
+ "sourcesContent": ["import { dir } from '../def.js';\n\n/** A boolean signal that is true while a request started from this element (or one inside it) is in flight. */\nexport const indicator = dir('indicator', 0, ({ el, key, value, cased, store, listen }) => {\n const path = key ? cased() : value.trim();\n // Requests are remembered by id at `started`, because the element that made one may have been\n // morphed away by the time it finishes.\n const mine = new Set<number>();\n store.set(path, false);\n listen(document, 'sigmx-fetch', (e: CustomEvent<{ el: Element; type: string; rid: number }>) => {\n const { el: from, type, rid } = e.detail;\n if (type === 'started' && el.contains(from)) mine.add(rid);\n else if (type === 'finished') mine.delete(rid);\n else return;\n store.set(path, mine.size > 0);\n });\n return () => store.set(path, false);\n});\n"],
5
+ "mappings": "AAAA,SAAS,WAAW;AAGb,MAAM,YAAY,IAAI,aAAa,GAAG,CAAC,EAAE,IAAI,KAAK,OAAO,OAAO,OAAO,OAAO,MAAM;AACzF,QAAM,OAAO,MAAM,MAAM,IAAI,MAAM,KAAK;AAGxC,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,IAAI,MAAM,KAAK;AACrB,SAAO,UAAU,eAAe,CAAC,MAA+D;AAC9F,UAAM,EAAE,IAAI,MAAM,MAAM,IAAI,IAAI,EAAE;AAClC,QAAI,SAAS,aAAa,GAAG,SAAS,IAAI,EAAG,MAAK,IAAI,GAAG;AAAA,aAChD,SAAS,WAAY,MAAK,OAAO,GAAG;AAAA,QACxC;AACL,UAAM,IAAI,MAAM,KAAK,OAAO,CAAC;AAAA,EAC/B,CAAC;AACD,SAAO,MAAM,MAAM,IAAI,MAAM,KAAK;AACpC,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,20 +1,21 @@
1
- import { attribute } from "../../kernel/index.js";
2
- const className = attribute({
3
- name: "class",
4
- value: "required",
5
- mount({ el, key, cased, evaluate, effect }) {
6
- const applied = /* @__PURE__ */ new Set();
7
- effect(() => {
8
- const map = key ? { [cased("kebab")]: evaluate() } : evaluate();
9
- for (const k in map) {
10
- for (const name of k.split(/\s+/).filter(Boolean)) {
11
- el.classList.toggle(name, !!map[k]);
12
- map[k] ? applied.add(name) : applied.delete(name);
13
- }
1
+ import { dir } from "../def.js";
2
+ const className = dir("class", 4, ({ el, key, cased, evaluate, effect }) => {
3
+ const applied = /* @__PURE__ */ new Set();
4
+ effect(() => {
5
+ const map = key ? { [cased("kebab")]: evaluate() } : evaluate();
6
+ const seen = /* @__PURE__ */ new Set();
7
+ for (const k in map) {
8
+ for (const name of k.split(/\s+/).filter(Boolean)) {
9
+ seen.add(name);
10
+ if (map[k]) {
11
+ if (!el.classList.contains(name)) applied.add(name);
12
+ el.classList.add(name);
13
+ } else if (applied.delete(name)) el.classList.remove(name);
14
14
  }
15
- });
16
- return () => el.classList.remove(...applied);
17
- }
15
+ }
16
+ for (const name of applied) if (!seen.has(name) && applied.delete(name)) el.classList.remove(name);
17
+ });
18
+ return () => el.classList.remove(...applied);
18
19
  });
19
20
  export {
20
21
  className
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/class-toggle.ts"],
4
- "sourcesContent": ["import { attribute } from '../../kernel/index.js';\n\n/** `class:active=\"expr\"` or `class=\"{ active: expr, 'a b': expr }\"`. */\nexport const className = attribute({\n name: 'class',\n value: 'required',\n mount({ el, key, cased, evaluate, effect }) {\n const applied = new Set<string>();\n effect(() => {\n const map: Record<string, unknown> = key ? { [cased('kebab')]: evaluate() } : evaluate();\n for (const k in map) {\n for (const name of k.split(/\\s+/).filter(Boolean)) {\n el.classList.toggle(name, !!map[k]);\n map[k] ? applied.add(name) : applied.delete(name);\n }\n }\n });\n return () => el.classList.remove(...applied);\n },\n});\n"],
5
- "mappings": "AAAA,SAAS,iBAAiB;AAGnB,MAAM,YAAY,UAAU;AAAA,EACjC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM,EAAE,IAAI,KAAK,OAAO,UAAU,OAAO,GAAG;AAC1C,UAAM,UAAU,oBAAI,IAAY;AAChC,WAAO,MAAM;AACX,YAAM,MAA+B,MAAM,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,SAAS;AACvF,iBAAW,KAAK,KAAK;AACnB,mBAAW,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO,GAAG;AACjD,aAAG,UAAU,OAAO,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AAClC,cAAI,CAAC,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ,OAAO,IAAI;AAAA,QAClD;AAAA,MACF;AAAA,IACF,CAAC;AACD,WAAO,MAAM,GAAG,UAAU,OAAO,GAAG,OAAO;AAAA,EAC7C;AACF,CAAC;",
4
+ "sourcesContent": ["import { dir } from '../def.js';\n\n/** `class:active=\"expr\"` or `class=\"{ active: expr, 'a b': expr }\"`. */\nexport const className = dir('class', 4, ({ el, key, cased, evaluate, effect }) => {\n const applied = new Set<string>(); // classes this directive turned on (and that were not already there)\n effect(() => {\n const map: Record<string, unknown> = key ? { [cased('kebab')]: evaluate() } : evaluate();\n const seen = new Set<string>();\n for (const k in map) {\n for (const name of k.split(/\\s+/).filter(Boolean)) {\n seen.add(name);\n if (map[k]) {\n if (!el.classList.contains(name)) applied.add(name);\n el.classList.add(name);\n } else if (applied.delete(name)) el.classList.remove(name);\n }\n }\n for (const name of applied) if (!seen.has(name) && applied.delete(name)) el.classList.remove(name); // key gone from the object\n });\n return () => el.classList.remove(...applied);\n});\n"],
5
+ "mappings": "AAAA,SAAS,WAAW;AAGb,MAAM,YAAY,IAAI,SAAS,GAAG,CAAC,EAAE,IAAI,KAAK,OAAO,UAAU,OAAO,MAAM;AACjF,QAAM,UAAU,oBAAI,IAAY;AAChC,SAAO,MAAM;AACX,UAAM,MAA+B,MAAM,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,EAAE,IAAI,SAAS;AACvF,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,KAAK;AACnB,iBAAW,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,OAAO,GAAG;AACjD,aAAK,IAAI,IAAI;AACb,YAAI,IAAI,CAAC,GAAG;AACV,cAAI,CAAC,GAAG,UAAU,SAAS,IAAI,EAAG,SAAQ,IAAI,IAAI;AAClD,aAAG,UAAU,IAAI,IAAI;AAAA,QACvB,WAAW,QAAQ,OAAO,IAAI,EAAG,IAAG,UAAU,OAAO,IAAI;AAAA,MAC3D;AAAA,IACF;AACA,eAAW,QAAQ,QAAS,KAAI,CAAC,KAAK,IAAI,IAAI,KAAK,QAAQ,OAAO,IAAI,EAAG,IAAG,UAAU,OAAO,IAAI;AAAA,EACnG,CAAC;AACD,SAAO,MAAM,GAAG,UAAU,OAAO,GAAG,OAAO;AAC7C,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,10 +1,5 @@
1
- import { attribute } from "../../kernel/index.js";
2
- const cloak = attribute({
3
- name: "cloak",
4
- key: "forbidden",
5
- value: "forbidden",
6
- mount: ({ el, attr }) => el.removeAttribute(attr)
7
- });
1
+ import { dir } from "../def.js";
2
+ const cloak = dir("cloak", 10, ({ el, attr }) => el.removeAttribute(attr));
8
3
  export {
9
4
  cloak
10
5
  };
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/cloak.ts"],
4
- "sourcesContent": ["import { attribute } from '../../kernel/index.js';\n\n/**\n * Removed as soon as the element mounts. Pair it with CSS that hides cloaked markup until then:\n * `[data-cloak] { display: none !important }`.\n */\nexport const cloak = attribute({\n name: 'cloak',\n key: 'forbidden',\n value: 'forbidden',\n mount: ({ el, attr }) => el.removeAttribute(attr),\n});\n"],
5
- "mappings": "AAAA,SAAS,iBAAiB;AAMnB,MAAM,QAAQ,UAAU;AAAA,EAC7B,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,OAAO,CAAC,EAAE,IAAI,KAAK,MAAM,GAAG,gBAAgB,IAAI;AAClD,CAAC;",
4
+ "sourcesContent": ["import { dir } from '../def.js';\n\n/**\n * Removed as soon as the element mounts. Pair it with CSS that hides cloaked markup until then:\n * `[data-cloak] { display: none !important }`.\n */\nexport const cloak = dir('cloak', 10, ({ el, attr }) => el.removeAttribute(attr));\n"],
5
+ "mappings": "AAAA,SAAS,WAAW;AAMb,MAAM,QAAQ,IAAI,SAAS,IAAI,CAAC,EAAE,IAAI,KAAK,MAAM,GAAG,gBAAgB,IAAI,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,40 +1,39 @@
1
- import { attribute, toMs } from "../../kernel/index.js";
2
- const collapse = attribute({
3
- name: "collapse",
4
- key: "forbidden",
5
- value: "required",
6
- mount({ el, mods, evaluate, effect, cleanup }) {
7
- const style = el.style;
8
- const ms = toMs(mods.get("duration"), 250);
9
- const min = mods.get("min")?.[0] ?? "0px";
10
- const instant = matchMedia("(prefers-reduced-motion: reduce)").matches;
11
- let timer;
12
- let first = true;
13
- let last;
14
- const settle = (open) => {
15
- style.transition = "";
16
- style.overflow = open ? "" : "hidden";
17
- style.height = open ? "" : min;
18
- };
19
- effect(() => {
20
- const open = !!evaluate();
21
- if (open === last) return;
22
- last = open;
23
- clearTimeout(timer);
24
- if (first || instant) {
25
- first = false;
26
- return settle(open);
27
- }
28
- const from = `${el.getBoundingClientRect().height}px`;
29
- style.overflow = "hidden";
30
- style.height = open ? min : from;
31
- void el.getBoundingClientRect();
32
- style.transition = `height ${ms}ms ease`;
33
- style.height = open ? `${el.scrollHeight}px` : min;
34
- timer = setTimeout(() => settle(open), ms + 20);
35
- });
36
- cleanup(() => clearTimeout(timer));
37
- }
1
+ import { toMs } from "../../kernel/index.js";
2
+ import { dir } from "../def.js";
3
+ const collapse = dir("collapse", 6, ({ el, mods, evaluate, effect, cleanup }) => {
4
+ const style = el.style;
5
+ const ms = toMs(mods.get("duration"), 250);
6
+ const instant = matchMedia("(prefers-reduced-motion: reduce)").matches;
7
+ const own = [style.height, style.overflow, style.transition];
8
+ let timer;
9
+ let first = true;
10
+ let last;
11
+ const settle = (open) => {
12
+ style.transition = "";
13
+ style.overflow = open ? "" : "hidden";
14
+ style.height = open ? "" : "0px";
15
+ };
16
+ effect(() => {
17
+ const open = !!evaluate();
18
+ if (open === last) return;
19
+ last = open;
20
+ clearTimeout(timer);
21
+ if (first || instant) {
22
+ first = false;
23
+ return settle(open);
24
+ }
25
+ const from = `${el.getBoundingClientRect().height}px`;
26
+ style.overflow = "hidden";
27
+ style.height = open ? "0px" : from;
28
+ void el.getBoundingClientRect();
29
+ style.transition = `height ${ms}ms ease`;
30
+ style.height = open ? `${el.scrollHeight}px` : "0px";
31
+ timer = setTimeout(() => settle(open), ms + 20);
32
+ });
33
+ cleanup(() => {
34
+ clearTimeout(timer);
35
+ [style.height, style.overflow, style.transition] = own;
36
+ });
38
37
  });
39
38
  export {
40
39
  collapse
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/plugins/directives/collapse.ts"],
4
- "sourcesContent": ["import { attribute, toMs } from '../../kernel/index.js';\n\n/**\n * Animates the element's height open and closed: `collapse=\"$open\"`.\n * Modifiers: `__duration.250ms`, `__min.40px` (collapsed height, default 0).\n */\nexport const collapse = attribute({\n name: 'collapse',\n key: 'forbidden',\n value: 'required',\n mount({ el, mods, evaluate, effect, cleanup }) {\n const style = (el as HTMLElement).style;\n const ms = toMs(mods.get('duration'), 250);\n const min = mods.get('min')?.[0] ?? '0px';\n const instant = matchMedia('(prefers-reduced-motion: reduce)').matches;\n let timer: ReturnType<typeof setTimeout> | undefined;\n let first = true;\n let last: boolean | undefined;\n const settle = (open: boolean) => {\n style.transition = '';\n style.overflow = open ? '' : 'hidden';\n style.height = open ? '' : min;\n };\n effect(() => {\n const open = !!evaluate();\n if (open === last) return;\n last = open;\n clearTimeout(timer);\n if (first || instant) {\n first = false;\n return settle(open);\n }\n const from = `${el.getBoundingClientRect().height}px`;\n style.overflow = 'hidden';\n style.height = open ? min : from;\n void el.getBoundingClientRect(); // commit the start height before transitioning\n style.transition = `height ${ms}ms ease`;\n style.height = open ? `${el.scrollHeight}px` : min;\n timer = setTimeout(() => settle(open), ms + 20);\n });\n cleanup(() => clearTimeout(timer));\n },\n});\n"],
5
- "mappings": "AAAA,SAAS,WAAW,YAAY;AAMzB,MAAM,WAAW,UAAU;AAAA,EAChC,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM,EAAE,IAAI,MAAM,UAAU,QAAQ,QAAQ,GAAG;AAC7C,UAAM,QAAS,GAAmB;AAClC,UAAM,KAAK,KAAK,KAAK,IAAI,UAAU,GAAG,GAAG;AACzC,UAAM,MAAM,KAAK,IAAI,KAAK,IAAI,CAAC,KAAK;AACpC,UAAM,UAAU,WAAW,kCAAkC,EAAE;AAC/D,QAAI;AACJ,QAAI,QAAQ;AACZ,QAAI;AACJ,UAAM,SAAS,CAAC,SAAkB;AAChC,YAAM,aAAa;AACnB,YAAM,WAAW,OAAO,KAAK;AAC7B,YAAM,SAAS,OAAO,KAAK;AAAA,IAC7B;AACA,WAAO,MAAM;AACX,YAAM,OAAO,CAAC,CAAC,SAAS;AACxB,UAAI,SAAS,KAAM;AACnB,aAAO;AACP,mBAAa,KAAK;AAClB,UAAI,SAAS,SAAS;AACpB,gBAAQ;AACR,eAAO,OAAO,IAAI;AAAA,MACpB;AACA,YAAM,OAAO,GAAG,GAAG,sBAAsB,EAAE,MAAM;AACjD,YAAM,WAAW;AACjB,YAAM,SAAS,OAAO,MAAM;AAC5B,WAAK,GAAG,sBAAsB;AAC9B,YAAM,aAAa,UAAU,EAAE;AAC/B,YAAM,SAAS,OAAO,GAAG,GAAG,YAAY,OAAO;AAC/C,cAAQ,WAAW,MAAM,OAAO,IAAI,GAAG,KAAK,EAAE;AAAA,IAChD,CAAC;AACD,YAAQ,MAAM,aAAa,KAAK,CAAC;AAAA,EACnC;AACF,CAAC;",
4
+ "sourcesContent": ["import { toMs } from '../../kernel/index.js';\nimport { dir } from '../def.js';\n\n/**\n * Animates the element's height open and closed: `collapse=\"$open\"`.\n * Modifiers: `__duration.250ms`, `__min.40px` (collapsed height, default 0).\n */\nexport const collapse = dir('collapse', 6, ({ el, mods, evaluate, effect, cleanup }) => {\n const style = (el as HTMLElement).style;\n const ms = toMs(mods.get('duration'), 250);\n const instant = matchMedia('(prefers-reduced-motion: reduce)').matches;\n const own = [style.height, style.overflow, style.transition];\n let timer: ReturnType<typeof setTimeout> | undefined;\n let first = true;\n let last: boolean | undefined;\n const settle = (open: boolean) => {\n style.transition = '';\n style.overflow = open ? '' : 'hidden';\n style.height = open ? '' : '0px';\n };\n effect(() => {\n const open = !!evaluate();\n if (open === last) return;\n last = open;\n clearTimeout(timer);\n if (first || instant) {\n first = false;\n return settle(open);\n }\n const from = `${el.getBoundingClientRect().height}px`;\n style.overflow = 'hidden';\n style.height = open ? '0px' : from;\n void el.getBoundingClientRect(); // commit the start height before transitioning\n style.transition = `height ${ms}ms ease`;\n style.height = open ? `${el.scrollHeight}px` : '0px';\n timer = setTimeout(() => settle(open), ms + 20);\n });\n cleanup(() => {\n clearTimeout(timer);\n [style.height, style.overflow, style.transition] = own;\n });\n});\n"],
5
+ "mappings": "AAAA,SAAS,YAAY;AACrB,SAAS,WAAW;AAMb,MAAM,WAAW,IAAI,YAAY,GAAG,CAAC,EAAE,IAAI,MAAM,UAAU,QAAQ,QAAQ,MAAM;AACtF,QAAM,QAAS,GAAmB;AAClC,QAAM,KAAK,KAAK,KAAK,IAAI,UAAU,GAAG,GAAG;AACzC,QAAM,UAAU,WAAW,kCAAkC,EAAE;AAC/D,QAAM,MAAM,CAAC,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU;AAC3D,MAAI;AACJ,MAAI,QAAQ;AACZ,MAAI;AACJ,QAAM,SAAS,CAAC,SAAkB;AAChC,UAAM,aAAa;AACnB,UAAM,WAAW,OAAO,KAAK;AAC7B,UAAM,SAAS,OAAO,KAAK;AAAA,EAC7B;AACA,SAAO,MAAM;AACX,UAAM,OAAO,CAAC,CAAC,SAAS;AACxB,QAAI,SAAS,KAAM;AACnB,WAAO;AACP,iBAAa,KAAK;AAClB,QAAI,SAAS,SAAS;AACpB,cAAQ;AACR,aAAO,OAAO,IAAI;AAAA,IACpB;AACA,UAAM,OAAO,GAAG,GAAG,sBAAsB,EAAE,MAAM;AACjD,UAAM,WAAW;AACjB,UAAM,SAAS,OAAO,QAAQ;AAC9B,SAAK,GAAG,sBAAsB;AAC9B,UAAM,aAAa,UAAU,EAAE;AAC/B,UAAM,SAAS,OAAO,GAAG,GAAG,YAAY,OAAO;AAC/C,YAAQ,WAAW,MAAM,OAAO,IAAI,GAAG,KAAK,EAAE;AAAA,EAChD,CAAC;AACD,UAAQ,MAAM;AACZ,iBAAa,KAAK;AAClB,KAAC,MAAM,QAAQ,MAAM,UAAU,MAAM,UAAU,IAAI;AAAA,EACrD,CAAC;AACH,CAAC;",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,8 @@
1
- import { attribute, expand } from "../../kernel/index.js";
2
- const signals = attribute({
3
- name: "signals",
4
- value: "required",
5
- mount({ key, cased, evaluate, store, mods }) {
6
- const v = evaluate();
7
- store.merge(key ? expand({}, cased(), v) : v, { ifMissing: mods.has("ifmissing") });
8
- }
1
+ import { expand } from "../../kernel/index.js";
2
+ import { dir } from "../def.js";
3
+ const signals = dir("signals", 4, ({ key, cased, evaluate, store, mods }) => {
4
+ const v = evaluate();
5
+ store.merge(key ? expand({}, cased(), v) : v, { ifMissing: mods.has("ifmissing") });
9
6
  });
10
7
  export {
11
8
  signals