effect-start 0.18.0 → 0.20.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 (203) hide show
  1. package/README.md +3 -3
  2. package/dist/Development.d.ts +8 -3
  3. package/dist/Development.js +14 -7
  4. package/dist/Effectify.d.ts +212 -0
  5. package/dist/Effectify.js +19 -0
  6. package/dist/FilePathPattern.d.ts +29 -0
  7. package/dist/FilePathPattern.js +86 -0
  8. package/dist/FileRouter.d.ts +39 -41
  9. package/dist/FileRouter.js +104 -158
  10. package/dist/FileRouterCodegen.d.ts +7 -8
  11. package/dist/FileRouterCodegen.js +97 -66
  12. package/dist/PlatformError.d.ts +46 -0
  13. package/dist/PlatformError.js +43 -0
  14. package/dist/PlatformRuntime.d.ts +27 -0
  15. package/dist/PlatformRuntime.js +51 -0
  16. package/dist/Route.d.ts +6 -2
  17. package/dist/Route.js +22 -0
  18. package/dist/RouteBody.d.ts +1 -1
  19. package/dist/RouteHttp.d.ts +1 -1
  20. package/dist/RouteHttp.js +12 -19
  21. package/dist/RouteMount.d.ts +2 -1
  22. package/dist/Start.d.ts +33 -6
  23. package/dist/Start.js +31 -13
  24. package/dist/Unique.d.ts +50 -0
  25. package/dist/Unique.js +187 -0
  26. package/dist/bun/BunHttpServer.js +5 -6
  27. package/dist/bun/BunPlatformHttpServer.d.ts +10 -0
  28. package/dist/bun/BunPlatformHttpServer.js +53 -0
  29. package/dist/bun/BunRoute.d.ts +4 -6
  30. package/dist/bun/BunRoute.js +10 -18
  31. package/dist/bun/BunRuntime.d.ts +2 -1
  32. package/dist/bun/BunRuntime.js +10 -5
  33. package/dist/bun/BunServer.d.ts +33 -0
  34. package/dist/bun/BunServer.js +133 -0
  35. package/dist/bun/BunServerRequest.d.ts +60 -0
  36. package/dist/bun/BunServerRequest.js +252 -0
  37. package/dist/bun/index.d.ts +1 -1
  38. package/dist/bun/index.js +1 -1
  39. package/dist/datastar/actions/fetch.d.ts +30 -0
  40. package/dist/datastar/actions/fetch.js +411 -0
  41. package/dist/datastar/actions/peek.d.ts +1 -0
  42. package/dist/datastar/actions/peek.js +14 -0
  43. package/dist/datastar/actions/setAll.d.ts +1 -0
  44. package/dist/datastar/actions/setAll.js +13 -0
  45. package/dist/datastar/actions/toggleAll.d.ts +1 -0
  46. package/dist/datastar/actions/toggleAll.js +13 -0
  47. package/dist/datastar/attributes/attr.d.ts +1 -0
  48. package/dist/datastar/attributes/attr.js +49 -0
  49. package/dist/datastar/attributes/bind.d.ts +1 -0
  50. package/dist/datastar/attributes/bind.js +183 -0
  51. package/dist/datastar/attributes/class.d.ts +1 -0
  52. package/dist/datastar/attributes/class.js +50 -0
  53. package/dist/datastar/attributes/computed.d.ts +1 -0
  54. package/dist/datastar/attributes/computed.js +27 -0
  55. package/dist/datastar/attributes/effect.d.ts +1 -0
  56. package/dist/datastar/attributes/effect.js +10 -0
  57. package/dist/datastar/attributes/indicator.d.ts +1 -0
  58. package/dist/datastar/attributes/indicator.js +32 -0
  59. package/dist/datastar/attributes/init.d.ts +1 -0
  60. package/dist/datastar/attributes/init.js +27 -0
  61. package/dist/datastar/attributes/jsonSignals.d.ts +1 -0
  62. package/dist/datastar/attributes/jsonSignals.js +31 -0
  63. package/dist/datastar/attributes/on.d.ts +1 -0
  64. package/dist/datastar/attributes/on.js +59 -0
  65. package/dist/datastar/attributes/onIntersect.d.ts +1 -0
  66. package/dist/datastar/attributes/onIntersect.js +54 -0
  67. package/dist/datastar/attributes/onInterval.d.ts +1 -0
  68. package/dist/datastar/attributes/onInterval.js +31 -0
  69. package/dist/datastar/attributes/onSignalPatch.d.ts +1 -0
  70. package/dist/datastar/attributes/onSignalPatch.js +44 -0
  71. package/dist/datastar/attributes/ref.d.ts +1 -0
  72. package/dist/datastar/attributes/ref.js +11 -0
  73. package/dist/datastar/attributes/show.d.ts +1 -0
  74. package/dist/datastar/attributes/show.js +32 -0
  75. package/dist/datastar/attributes/signals.d.ts +1 -0
  76. package/dist/datastar/attributes/signals.js +18 -0
  77. package/dist/datastar/attributes/style.d.ts +1 -0
  78. package/dist/datastar/attributes/style.js +56 -0
  79. package/dist/datastar/attributes/text.d.ts +1 -0
  80. package/dist/datastar/attributes/text.js +27 -0
  81. package/dist/datastar/engine.d.ts +156 -0
  82. package/dist/datastar/engine.js +971 -0
  83. package/dist/datastar/index.d.ts +24 -0
  84. package/dist/datastar/index.js +24 -0
  85. package/dist/datastar/load.d.ts +24 -0
  86. package/dist/datastar/load.js +24 -0
  87. package/dist/datastar/utils.d.ts +51 -0
  88. package/dist/datastar/utils.js +205 -0
  89. package/dist/datastar/watchers/patchElements.d.ts +1 -0
  90. package/dist/datastar/watchers/patchElements.js +420 -0
  91. package/dist/datastar/watchers/patchSignals.d.ts +1 -0
  92. package/dist/datastar/watchers/patchSignals.js +15 -0
  93. package/dist/index.d.ts +1 -0
  94. package/dist/index.js +1 -0
  95. package/dist/node/Effectify.d.ts +209 -0
  96. package/dist/node/Effectify.js +19 -0
  97. package/dist/node/FileSystem.d.ts +3 -5
  98. package/dist/node/FileSystem.js +42 -62
  99. package/dist/node/NodeFileSystem.d.ts +7 -0
  100. package/dist/node/NodeFileSystem.js +420 -0
  101. package/dist/node/NodeUtils.d.ts +2 -0
  102. package/dist/node/NodeUtils.js +20 -0
  103. package/dist/node/PlatformError.d.ts +46 -0
  104. package/dist/node/PlatformError.js +43 -0
  105. package/dist/testing/TestLogger.js +1 -1
  106. package/dist/x/tailwind/plugin.js +1 -1
  107. package/package.json +18 -7
  108. package/src/Development.ts +36 -40
  109. package/src/Effectify.ts +269 -0
  110. package/src/FilePathPattern.ts +115 -0
  111. package/src/FileRouter.ts +178 -255
  112. package/src/FileRouterCodegen.ts +135 -92
  113. package/src/PlatformError.ts +117 -0
  114. package/src/PlatformRuntime.ts +108 -0
  115. package/src/Route.ts +31 -2
  116. package/src/RouteBody.ts +1 -1
  117. package/src/RouteHttp.ts +15 -29
  118. package/src/RouteMount.ts +1 -1
  119. package/src/Start.ts +61 -27
  120. package/src/Unique.ts +232 -0
  121. package/src/bun/BunPlatformHttpServer.ts +88 -0
  122. package/src/bun/BunRoute.ts +14 -24
  123. package/src/bun/BunRuntime.ts +21 -5
  124. package/src/bun/BunServer.ts +228 -0
  125. package/src/bun/index.ts +1 -1
  126. package/src/datastar/README.md +18 -0
  127. package/src/datastar/actions/fetch.ts +609 -0
  128. package/src/datastar/actions/peek.ts +17 -0
  129. package/src/datastar/actions/setAll.ts +20 -0
  130. package/src/datastar/actions/toggleAll.ts +20 -0
  131. package/src/datastar/attributes/attr.ts +50 -0
  132. package/src/datastar/attributes/bind.ts +220 -0
  133. package/src/datastar/attributes/class.ts +57 -0
  134. package/src/datastar/attributes/computed.ts +33 -0
  135. package/src/datastar/attributes/effect.ts +11 -0
  136. package/src/datastar/attributes/indicator.ts +39 -0
  137. package/src/datastar/attributes/init.ts +35 -0
  138. package/src/datastar/attributes/jsonSignals.ts +38 -0
  139. package/src/datastar/attributes/on.ts +71 -0
  140. package/src/datastar/attributes/onIntersect.ts +65 -0
  141. package/src/datastar/attributes/onInterval.ts +39 -0
  142. package/src/datastar/attributes/onSignalPatch.ts +63 -0
  143. package/src/datastar/attributes/ref.ts +12 -0
  144. package/src/datastar/attributes/show.ts +33 -0
  145. package/src/datastar/attributes/signals.ts +22 -0
  146. package/src/datastar/attributes/style.ts +63 -0
  147. package/src/datastar/attributes/text.ts +30 -0
  148. package/src/datastar/engine.ts +1341 -0
  149. package/src/datastar/index.ts +25 -0
  150. package/src/datastar/utils.ts +286 -0
  151. package/src/datastar/watchers/patchElements.ts +554 -0
  152. package/src/datastar/watchers/patchSignals.ts +15 -0
  153. package/src/index.ts +1 -0
  154. package/src/node/{FileSystem.ts → NodeFileSystem.ts} +59 -97
  155. package/src/node/{Utils.ts → NodeUtils.ts} +2 -0
  156. package/src/testing/TestLogger.ts +1 -1
  157. package/src/x/tailwind/plugin.ts +1 -1
  158. package/dist/Random.d.ts +0 -5
  159. package/dist/Random.js +0 -49
  160. package/src/Commander.test.ts +0 -1639
  161. package/src/ContentNegotiation.test.ts +0 -603
  162. package/src/Development.test.ts +0 -119
  163. package/src/Entity.test.ts +0 -592
  164. package/src/FileRouterCodegen.todo.ts +0 -1133
  165. package/src/FileRouterPattern.test.ts +0 -147
  166. package/src/FileRouterPattern.ts +0 -59
  167. package/src/FileRouter_files.test.ts +0 -64
  168. package/src/FileRouter_path.test.ts +0 -145
  169. package/src/FileRouter_tree.test.ts +0 -132
  170. package/src/Http.test.ts +0 -319
  171. package/src/HttpAppExtra.test.ts +0 -103
  172. package/src/HttpUtils.test.ts +0 -85
  173. package/src/PathPattern.test.ts +0 -648
  174. package/src/Random.ts +0 -59
  175. package/src/RouteBody.test.ts +0 -232
  176. package/src/RouteHook.test.ts +0 -40
  177. package/src/RouteHttp.test.ts +0 -2909
  178. package/src/RouteMount.test.ts +0 -481
  179. package/src/RouteSchema.test.ts +0 -427
  180. package/src/RouteSse.test.ts +0 -249
  181. package/src/RouteTree.test.ts +0 -494
  182. package/src/RouteTrie.test.ts +0 -322
  183. package/src/RouterPattern.test.ts +0 -676
  184. package/src/RouterPattern.ts +0 -416
  185. package/src/StartApp.ts +0 -47
  186. package/src/Values.test.ts +0 -263
  187. package/src/bun/BunBundle.test.ts +0 -268
  188. package/src/bun/BunBundle_imports.test.ts +0 -48
  189. package/src/bun/BunHttpServer.test.ts +0 -251
  190. package/src/bun/BunHttpServer.ts +0 -306
  191. package/src/bun/BunImportTrackerPlugin.test.ts +0 -77
  192. package/src/bun/BunRoute.test.ts +0 -162
  193. package/src/bundler/BundleHttp.test.ts +0 -132
  194. package/src/effect/HttpRouter.test.ts +0 -548
  195. package/src/experimental/EncryptedCookies.test.ts +0 -488
  196. package/src/hyper/HyperHtml.test.ts +0 -209
  197. package/src/hyper/HyperRoute.test.tsx +0 -197
  198. package/src/middlewares/BasicAuthMiddleware.test.ts +0 -84
  199. package/src/testing/TestHttpClient.test.ts +0 -83
  200. package/src/testing/TestLogger.test.ts +0 -51
  201. package/src/x/datastar/Datastar.test.ts +0 -266
  202. package/src/x/tailwind/TailwindPlugin.test.ts +0 -333
  203. /package/src/bun/{BunHttpServer_web.ts → BunServerRequest.ts} +0 -0
@@ -0,0 +1,183 @@
1
+ import { attribute } from "../engine.js";
2
+ import { effect, getPath, mergePaths, } from "../engine.js";
3
+ import { aliasify, modifyCasing, } from "../utils.js";
4
+ const dataURIRegex = /^data:(?<mime>[^;]+);base64,(?<contents>.*)$/;
5
+ const empty = Symbol("empty");
6
+ const aliasedBind = aliasify("bind");
7
+ attribute({
8
+ name: "bind",
9
+ requirement: "exclusive",
10
+ apply({ el, key, mods, value, error }) {
11
+ const signalName = key != null ? modifyCasing(key, mods) : value;
12
+ let get = (el, type) => type === "number" ? +el.value : el.value;
13
+ let set = (value) => {
14
+ ;
15
+ el.value = `${value}`;
16
+ };
17
+ if (el instanceof HTMLInputElement) {
18
+ switch (el.type) {
19
+ case "range":
20
+ case "number":
21
+ get = (el, type) => type === "string" ? el.value : +el.value;
22
+ break;
23
+ case "checkbox":
24
+ get = (el, type) => {
25
+ if (el.value !== "on") {
26
+ if (type === "boolean") {
27
+ return el.checked;
28
+ }
29
+ else {
30
+ return el.checked ? el.value : "";
31
+ }
32
+ }
33
+ else {
34
+ if (type === "string") {
35
+ return el.checked ? el.value : "";
36
+ }
37
+ else {
38
+ return el.checked;
39
+ }
40
+ }
41
+ };
42
+ set = (value) => {
43
+ el.checked = typeof value === "string" ? value === el.value : value;
44
+ };
45
+ break;
46
+ case "radio":
47
+ if (!el.getAttribute("name")?.length) {
48
+ el.setAttribute("name", signalName);
49
+ }
50
+ get = (el, type) => el.checked ? (type === "number" ? +el.value : el.value) : empty;
51
+ set = (value) => {
52
+ el.checked = value === (typeof value === "number"
53
+ ? +el.value
54
+ : el.value);
55
+ };
56
+ break;
57
+ case "file": {
58
+ const syncSignal = () => {
59
+ const files = [...(el.files || [])];
60
+ const signalFiles = [];
61
+ Promise
62
+ .all(files.map((f) => new Promise((resolve) => {
63
+ const reader = new FileReader();
64
+ reader.onload = () => {
65
+ if (typeof reader.result !== "string") {
66
+ throw error("InvalidFileResultType", {
67
+ resultType: typeof reader.result,
68
+ });
69
+ }
70
+ const match = reader.result.match(dataURIRegex);
71
+ if (!match?.groups) {
72
+ throw error("InvalidDataUri", {
73
+ result: reader.result,
74
+ });
75
+ }
76
+ signalFiles.push({
77
+ name: f.name,
78
+ contents: match.groups.contents,
79
+ mime: match.groups.mime,
80
+ });
81
+ };
82
+ reader.onloadend = () => resolve();
83
+ reader.readAsDataURL(f);
84
+ })))
85
+ .then(() => {
86
+ mergePaths([[signalName, signalFiles]]);
87
+ });
88
+ };
89
+ el.addEventListener("change", syncSignal);
90
+ el.addEventListener("input", syncSignal);
91
+ return () => {
92
+ el.removeEventListener("change", syncSignal);
93
+ el.removeEventListener("input", syncSignal);
94
+ };
95
+ }
96
+ }
97
+ }
98
+ else if (el instanceof HTMLSelectElement) {
99
+ if (el.multiple) {
100
+ const typeMap = new Map();
101
+ get = (el) => [...el.selectedOptions].map((option) => {
102
+ const type = typeMap.get(option.value);
103
+ return type === "string" || type == null
104
+ ? option.value
105
+ : +option.value;
106
+ });
107
+ set = (value) => {
108
+ for (const option of el.options) {
109
+ if (value.includes(option.value)) {
110
+ typeMap.set(option.value, "string");
111
+ option.selected = true;
112
+ }
113
+ else if (value.includes(+option.value)) {
114
+ typeMap.set(option.value, "number");
115
+ option.selected = true;
116
+ }
117
+ else {
118
+ option.selected = false;
119
+ }
120
+ }
121
+ };
122
+ }
123
+ }
124
+ else if (el instanceof HTMLTextAreaElement) {
125
+ // default case
126
+ }
127
+ else {
128
+ // web component
129
+ get = (el) => "value" in el ? el.value : el.getAttribute("value");
130
+ set = (value) => {
131
+ if ("value" in el) {
132
+ el.value = value;
133
+ }
134
+ else {
135
+ el.setAttribute("value", value);
136
+ }
137
+ };
138
+ }
139
+ const initialValue = getPath(signalName);
140
+ const type = typeof initialValue;
141
+ let path = signalName;
142
+ if (Array.isArray(initialValue)
143
+ && !(el instanceof HTMLSelectElement && el.multiple)) {
144
+ const signalNameKebab = key ? key : value;
145
+ const inputs = document.querySelectorAll(`[${aliasedBind}\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}="${CSS.escape(signalNameKebab)}"]`);
146
+ const paths = [];
147
+ let i = 0;
148
+ for (const input of inputs) {
149
+ paths.push([`${path}.${i}`, get(input, "none")]);
150
+ if (el === input) {
151
+ break;
152
+ }
153
+ i++;
154
+ }
155
+ mergePaths(paths, { ifMissing: true });
156
+ path = `${path}.${i}`;
157
+ }
158
+ else {
159
+ mergePaths([[path, get(el, type)]], {
160
+ ifMissing: true,
161
+ });
162
+ }
163
+ const syncSignal = () => {
164
+ const signalValue = getPath(path);
165
+ if (signalValue != null) {
166
+ const value = get(el, typeof signalValue);
167
+ if (value !== empty) {
168
+ mergePaths([[path, value]]);
169
+ }
170
+ }
171
+ };
172
+ el.addEventListener("input", syncSignal);
173
+ el.addEventListener("change", syncSignal);
174
+ const cleanup = effect(() => {
175
+ set(getPath(path));
176
+ });
177
+ return () => {
178
+ cleanup();
179
+ el.removeEventListener("input", syncSignal);
180
+ el.removeEventListener("change", syncSignal);
181
+ };
182
+ },
183
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,50 @@
1
+ import { attribute } from "../engine.js";
2
+ import { effect } from "../engine.js";
3
+ import { modifyCasing } from "../utils.js";
4
+ attribute({
5
+ name: "class",
6
+ requirement: {
7
+ value: "must",
8
+ },
9
+ returnsValue: true,
10
+ apply({ key, el, mods, rx }) {
11
+ key &&= modifyCasing(key, mods, "kebab");
12
+ let classes;
13
+ const callback = () => {
14
+ observer.disconnect();
15
+ classes = key
16
+ ? { [key]: rx() }
17
+ : rx();
18
+ for (const k in classes) {
19
+ const classNames = k.split(/\s+/).filter((cn) => cn.length > 0);
20
+ if (classes[k]) {
21
+ for (const name of classNames) {
22
+ if (!el.classList.contains(name)) {
23
+ el.classList.add(name);
24
+ }
25
+ }
26
+ }
27
+ else {
28
+ for (const name of classNames) {
29
+ if (el.classList.contains(name)) {
30
+ el.classList.remove(name);
31
+ }
32
+ }
33
+ }
34
+ }
35
+ observer.observe(el, { attributeFilter: ["class"] });
36
+ };
37
+ const observer = new MutationObserver(callback);
38
+ const cleanup = effect(callback);
39
+ return () => {
40
+ observer.disconnect();
41
+ cleanup();
42
+ for (const k in classes) {
43
+ const classNames = k.split(/\s+/).filter((cn) => cn.length > 0);
44
+ for (const name of classNames) {
45
+ el.classList.remove(name);
46
+ }
47
+ }
48
+ };
49
+ },
50
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { attribute } from "../engine.js";
2
+ import { computed, mergePatch, mergePaths, } from "../engine.js";
3
+ import { modifyCasing, updateLeaves, } from "../utils.js";
4
+ attribute({
5
+ name: "computed",
6
+ requirement: {
7
+ value: "must",
8
+ },
9
+ returnsValue: true,
10
+ apply({ key, mods, rx, error }) {
11
+ if (key) {
12
+ mergePaths([[modifyCasing(key, mods), computed(rx)]]);
13
+ }
14
+ else {
15
+ const patch = Object.assign({}, rx());
16
+ updateLeaves(patch, (old) => {
17
+ if (typeof old === "function") {
18
+ return computed(old);
19
+ }
20
+ else {
21
+ throw error("ComputedExpectedFunction");
22
+ }
23
+ });
24
+ mergePatch(patch);
25
+ }
26
+ },
27
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import { attribute } from "../engine.js";
2
+ import { effect } from "../engine.js";
3
+ attribute({
4
+ name: "effect",
5
+ requirement: {
6
+ key: "denied",
7
+ value: "must",
8
+ },
9
+ apply: ({ rx }) => effect(rx),
10
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { DATASTAR_FETCH_EVENT } from "../engine.js";
2
+ import { attribute } from "../engine.js";
3
+ import { mergePaths } from "../engine.js";
4
+ import { modifyCasing } from "../utils.js";
5
+ import { FINISHED, STARTED, } from "../actions/fetch.js";
6
+ attribute({
7
+ name: "indicator",
8
+ requirement: "exclusive",
9
+ apply({ el, key, mods, value }) {
10
+ const signalName = key != null ? modifyCasing(key, mods) : value;
11
+ mergePaths([[signalName, false]]);
12
+ const watcher = ((event) => {
13
+ const { type, el: elt } = event.detail;
14
+ if (elt !== el) {
15
+ return;
16
+ }
17
+ switch (type) {
18
+ case STARTED:
19
+ mergePaths([[signalName, true]]);
20
+ break;
21
+ case FINISHED:
22
+ mergePaths([[signalName, false]]);
23
+ break;
24
+ }
25
+ });
26
+ document.addEventListener(DATASTAR_FETCH_EVENT, watcher);
27
+ return () => {
28
+ mergePaths([[signalName, false]]);
29
+ document.removeEventListener(DATASTAR_FETCH_EVENT, watcher);
30
+ };
31
+ },
32
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ import { attribute } from "../engine.js";
2
+ import { beginBatch, endBatch, } from "../engine.js";
3
+ import { delay, modifyViewTransition, tagToMs, } from "../utils.js";
4
+ attribute({
5
+ name: "init",
6
+ requirement: {
7
+ key: "denied",
8
+ value: "must",
9
+ },
10
+ apply({ rx, mods }) {
11
+ let callback = () => {
12
+ beginBatch();
13
+ rx();
14
+ endBatch();
15
+ };
16
+ callback = modifyViewTransition(callback, mods);
17
+ let wait = 0;
18
+ const delayArgs = mods.get("delay");
19
+ if (delayArgs) {
20
+ wait = tagToMs(delayArgs);
21
+ if (wait > 0) {
22
+ callback = delay(callback, wait);
23
+ }
24
+ }
25
+ callback();
26
+ },
27
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { attribute } from "../engine.js";
2
+ import { effect, filtered, } from "../engine.js";
3
+ import { jsStrToObject } from "../utils.js";
4
+ attribute({
5
+ name: "json-signals",
6
+ requirement: {
7
+ key: "denied",
8
+ },
9
+ apply({ el, value, mods }) {
10
+ const spaces = mods.has("terse") ? 0 : 2;
11
+ let filters = {};
12
+ if (value) {
13
+ filters = jsStrToObject(value);
14
+ }
15
+ const callback = () => {
16
+ observer.disconnect();
17
+ el.textContent = JSON.stringify(filtered(filters), null, spaces);
18
+ observer.observe(el, {
19
+ childList: true,
20
+ characterData: true,
21
+ subtree: true,
22
+ });
23
+ };
24
+ const observer = new MutationObserver(callback);
25
+ const cleanup = effect(callback);
26
+ return () => {
27
+ observer.disconnect();
28
+ cleanup();
29
+ };
30
+ },
31
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ import { DATASTAR_FETCH_EVENT, DATASTAR_SIGNAL_PATCH_EVENT, } from "../engine.js";
2
+ import { attribute } from "../engine.js";
3
+ import { beginBatch, endBatch, } from "../engine.js";
4
+ import { modifyCasing, modifyTiming, modifyViewTransition, } from "../utils.js";
5
+ attribute({
6
+ name: "on",
7
+ requirement: "must",
8
+ argNames: ["evt"],
9
+ apply({ el, key, mods, rx }) {
10
+ let target = el;
11
+ if (mods.has("window"))
12
+ target = window;
13
+ let callback = (evt) => {
14
+ if (evt) {
15
+ if (mods.has("prevent")) {
16
+ evt.preventDefault();
17
+ }
18
+ if (mods.has("stop")) {
19
+ evt.stopPropagation();
20
+ }
21
+ }
22
+ beginBatch();
23
+ rx(evt);
24
+ endBatch();
25
+ };
26
+ callback = modifyViewTransition(callback, mods);
27
+ callback = modifyTiming(callback, mods);
28
+ const evtListOpts = {
29
+ capture: mods.has("capture"),
30
+ passive: mods.has("passive"),
31
+ once: mods.has("once"),
32
+ };
33
+ if (mods.has("outside")) {
34
+ target = document;
35
+ const cb = callback;
36
+ callback = (evt) => {
37
+ if (!el.contains(evt?.target)) {
38
+ cb(evt);
39
+ }
40
+ };
41
+ }
42
+ const eventName = modifyCasing(key, mods, "kebab");
43
+ if (eventName === DATASTAR_FETCH_EVENT
44
+ || eventName === DATASTAR_SIGNAL_PATCH_EVENT) {
45
+ target = document;
46
+ }
47
+ if (el instanceof HTMLFormElement && eventName === "submit") {
48
+ const cb = callback;
49
+ callback = (evt) => {
50
+ evt?.preventDefault();
51
+ cb(evt);
52
+ };
53
+ }
54
+ target.addEventListener(eventName, callback, evtListOpts);
55
+ return () => {
56
+ target.removeEventListener(eventName, callback);
57
+ };
58
+ },
59
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,54 @@
1
+ import { attribute } from "../engine.js";
2
+ import { beginBatch, endBatch, } from "../engine.js";
3
+ import { clamp, modifyTiming, modifyViewTransition, } from "../utils.js";
4
+ const once = new WeakSet();
5
+ attribute({
6
+ name: "on-intersect",
7
+ requirement: {
8
+ key: "denied",
9
+ value: "must",
10
+ },
11
+ apply({ el, mods, rx }) {
12
+ let callback = () => {
13
+ beginBatch();
14
+ rx();
15
+ endBatch();
16
+ };
17
+ callback = modifyViewTransition(callback, mods);
18
+ callback = modifyTiming(callback, mods);
19
+ const options = { threshold: 0 };
20
+ if (mods.has("full")) {
21
+ options.threshold = 1;
22
+ }
23
+ else if (mods.has("half")) {
24
+ options.threshold = 0.5;
25
+ }
26
+ else if (mods.get("threshold")) {
27
+ options.threshold = clamp(Number(mods.get("threshold")), 0, 100) / 100;
28
+ }
29
+ const exit = mods.has("exit");
30
+ let observer = new IntersectionObserver((entries) => {
31
+ for (const entry of entries) {
32
+ if (entry.isIntersecting !== exit) {
33
+ callback();
34
+ if (observer && once.has(el)) {
35
+ observer.disconnect();
36
+ }
37
+ }
38
+ }
39
+ }, options);
40
+ observer.observe(el);
41
+ if (mods.has("once")) {
42
+ once.add(el);
43
+ }
44
+ return () => {
45
+ if (!mods.has("once")) {
46
+ once.delete(el);
47
+ }
48
+ if (observer) {
49
+ observer.disconnect();
50
+ observer = null;
51
+ }
52
+ };
53
+ },
54
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ import { attribute } from "../engine.js";
2
+ import { beginBatch, endBatch, } from "../engine.js";
3
+ import { modifyViewTransition, tagHas, tagToMs, } from "../utils.js";
4
+ attribute({
5
+ name: "on-interval",
6
+ requirement: {
7
+ key: "denied",
8
+ value: "must",
9
+ },
10
+ apply({ mods, rx }) {
11
+ let callback = () => {
12
+ beginBatch();
13
+ rx();
14
+ endBatch();
15
+ };
16
+ callback = modifyViewTransition(callback, mods);
17
+ let duration = 1000;
18
+ const durationArgs = mods.get("duration");
19
+ if (durationArgs) {
20
+ duration = tagToMs(durationArgs);
21
+ const leading = tagHas(durationArgs, "leading", false);
22
+ if (leading) {
23
+ callback();
24
+ }
25
+ }
26
+ const intervalId = setInterval(callback, duration);
27
+ return () => {
28
+ clearInterval(intervalId);
29
+ };
30
+ },
31
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { DATASTAR_SIGNAL_PATCH_EVENT } from "../engine.js";
2
+ import { attribute } from "../engine.js";
3
+ import { beginBatch, endBatch, filtered, } from "../engine.js";
4
+ import { aliasify, isEmpty, jsStrToObject, modifyTiming, } from "../utils.js";
5
+ attribute({
6
+ name: "on-signal-patch",
7
+ requirement: {
8
+ value: "must",
9
+ },
10
+ argNames: ["patch"],
11
+ returnsValue: true,
12
+ apply({ el, key, mods, rx, error }) {
13
+ if (!!key && key !== "filter") {
14
+ throw error("KeyNotAllowed");
15
+ }
16
+ const filterAttr = aliasify(`${this.name}-filter`);
17
+ const filtersRaw = el.getAttribute(filterAttr);
18
+ let filters = {};
19
+ if (filtersRaw) {
20
+ filters = jsStrToObject(filtersRaw);
21
+ }
22
+ let running = false;
23
+ const callback = modifyTiming((evt) => {
24
+ if (running)
25
+ return;
26
+ const watched = filtered(filters, evt.detail);
27
+ if (!isEmpty(watched)) {
28
+ running = true;
29
+ beginBatch();
30
+ try {
31
+ rx(watched);
32
+ }
33
+ finally {
34
+ endBatch();
35
+ running = false;
36
+ }
37
+ }
38
+ }, mods);
39
+ document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback);
40
+ return () => {
41
+ document.removeEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback);
42
+ };
43
+ },
44
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { attribute } from "../engine.js";
2
+ import { mergePaths } from "../engine.js";
3
+ import { modifyCasing } from "../utils.js";
4
+ attribute({
5
+ name: "ref",
6
+ requirement: "exclusive",
7
+ apply({ el, key, mods, value }) {
8
+ const signalName = key != null ? modifyCasing(key, mods) : value;
9
+ mergePaths([[signalName, el]]);
10
+ },
11
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { attribute } from "../engine.js";
2
+ import { effect } from "../engine.js";
3
+ const NONE = "none";
4
+ const DISPLAY = "display";
5
+ attribute({
6
+ name: "show",
7
+ requirement: {
8
+ key: "denied",
9
+ value: "must",
10
+ },
11
+ returnsValue: true,
12
+ apply({ el, rx }) {
13
+ const update = () => {
14
+ observer.disconnect();
15
+ const shouldShow = rx();
16
+ if (shouldShow) {
17
+ if (el.style.display === NONE)
18
+ el.style.removeProperty(DISPLAY);
19
+ }
20
+ else {
21
+ el.style.setProperty(DISPLAY, NONE);
22
+ }
23
+ observer.observe(el, { attributeFilter: ["style"] });
24
+ };
25
+ const observer = new MutationObserver(update);
26
+ const cleanup = effect(update);
27
+ return () => {
28
+ observer.disconnect();
29
+ cleanup();
30
+ };
31
+ },
32
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { attribute } from "../engine.js";
2
+ import { mergePatch, mergePaths, } from "../engine.js";
3
+ import { modifyCasing } from "../utils.js";
4
+ attribute({
5
+ name: "signals",
6
+ returnsValue: true,
7
+ apply({ key, mods, rx }) {
8
+ const ifMissing = mods.has("ifmissing");
9
+ if (key) {
10
+ key = modifyCasing(key, mods);
11
+ mergePaths([[key, rx?.()]], { ifMissing });
12
+ }
13
+ else {
14
+ const patch = Object.assign({}, rx?.());
15
+ mergePatch(patch, { ifMissing });
16
+ }
17
+ },
18
+ });
@@ -0,0 +1 @@
1
+ export {};