@manyducks.co/dolla 2.0.0 → 3.0.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 (112) hide show
  1. package/README.md +133 -284
  2. package/dist/core/context.d.ts +22 -146
  3. package/dist/core/debug.d.ts +19 -0
  4. package/dist/core/index.d.ts +15 -16
  5. package/dist/core/markup/helpers.d.ts +34 -0
  6. package/dist/core/markup/html.d.ts +3 -0
  7. package/dist/core/{nodes → markup/nodes}/dom.d.ts +5 -4
  8. package/dist/core/markup/nodes/dynamic.d.ts +16 -0
  9. package/dist/core/markup/nodes/element.d.ts +14 -0
  10. package/dist/core/markup/nodes/portal.d.ts +15 -0
  11. package/dist/core/markup/nodes/repeat.d.ts +21 -0
  12. package/dist/core/markup/nodes/view.d.ts +17 -0
  13. package/dist/core/markup/scheduler.d.ts +1 -0
  14. package/dist/core/markup/types.d.ts +62 -0
  15. package/dist/core/markup/utils.d.ts +22 -0
  16. package/dist/core/ref.d.ts +6 -12
  17. package/dist/core/root.d.ts +36 -0
  18. package/dist/core/signals.d.ts +46 -76
  19. package/dist/core/symbols.d.ts +2 -0
  20. package/dist/core-BLkJ-xuh.js +242 -0
  21. package/dist/core-BLkJ-xuh.js.map +1 -0
  22. package/dist/http/index.d.ts +21 -33
  23. package/dist/http.js +89 -149
  24. package/dist/http.js.map +1 -1
  25. package/dist/index.js +4 -174
  26. package/dist/jsx-dev-runtime.d.ts +4 -3
  27. package/dist/jsx-dev-runtime.js +12 -9
  28. package/dist/jsx-dev-runtime.js.map +1 -1
  29. package/dist/jsx-runtime.d.ts +5 -4
  30. package/dist/jsx-runtime.js +17 -12
  31. package/dist/jsx-runtime.js.map +1 -1
  32. package/dist/router/index.d.ts +4 -3
  33. package/dist/router/router.d.ts +19 -162
  34. package/dist/router/store.d.ts +12 -0
  35. package/dist/router/types.d.ts +152 -0
  36. package/dist/router/utils.d.ts +99 -0
  37. package/dist/router/utils.test.d.ts +1 -0
  38. package/dist/router.js +428 -5
  39. package/dist/router.js.map +1 -1
  40. package/dist/signals-CMJPGr_M.js +354 -0
  41. package/dist/signals-CMJPGr_M.js.map +1 -0
  42. package/dist/translate/index.d.ts +82 -0
  43. package/dist/translate.js +125 -0
  44. package/dist/translate.js.map +1 -0
  45. package/dist/types.d.ts +21 -39
  46. package/dist/utils.d.ts +41 -29
  47. package/dist/utils.test.d.ts +1 -0
  48. package/dist/view-cBN-hn_T.js +360 -0
  49. package/dist/view-cBN-hn_T.js.map +1 -0
  50. package/dist/virtual/index.d.ts +1 -0
  51. package/dist/virtual/list.d.ts +53 -0
  52. package/package.json +19 -16
  53. package/dist/core/app.d.ts +0 -24
  54. package/dist/core/env.d.ts +0 -3
  55. package/dist/core/hooks.d.ts +0 -70
  56. package/dist/core/logger.d.ts +0 -42
  57. package/dist/core/logger.test.d.ts +0 -0
  58. package/dist/core/markup.d.ts +0 -82
  59. package/dist/core/markup.test.d.ts +0 -0
  60. package/dist/core/nodes/_markup.d.ts +0 -36
  61. package/dist/core/nodes/dynamic.d.ts +0 -22
  62. package/dist/core/nodes/element.d.ts +0 -27
  63. package/dist/core/nodes/portal.d.ts +0 -18
  64. package/dist/core/nodes/repeat.d.ts +0 -27
  65. package/dist/core/nodes/view.d.ts +0 -25
  66. package/dist/core/views/default-crash-view.d.ts +0 -25
  67. package/dist/core/views/for.d.ts +0 -21
  68. package/dist/core/views/fragment.d.ts +0 -7
  69. package/dist/core/views/portal.d.ts +0 -16
  70. package/dist/core/views/show.d.ts +0 -25
  71. package/dist/fragment-BahD_BJA.js +0 -7
  72. package/dist/fragment-BahD_BJA.js.map +0 -1
  73. package/dist/i18n/index.d.ts +0 -134
  74. package/dist/i18n.js +0 -309
  75. package/dist/i18n.js.map +0 -1
  76. package/dist/index-DRJlxs-Q.js +0 -535
  77. package/dist/index-DRJlxs-Q.js.map +0 -1
  78. package/dist/index.js.map +0 -1
  79. package/dist/logger-Aqi9m1CF.js +0 -565
  80. package/dist/logger-Aqi9m1CF.js.map +0 -1
  81. package/dist/markup-8jNhoqDe.js +0 -1089
  82. package/dist/markup-8jNhoqDe.js.map +0 -1
  83. package/dist/router/hooks.d.ts +0 -2
  84. package/dist/router/router.utils.d.ts +0 -93
  85. package/dist/typeChecking-5kmX0ulW.js +0 -65
  86. package/dist/typeChecking-5kmX0ulW.js.map +0 -1
  87. package/dist/typeChecking.d.ts +0 -95
  88. package/docs/buildless.md +0 -132
  89. package/docs/components.md +0 -238
  90. package/docs/hooks.md +0 -356
  91. package/docs/http.md +0 -178
  92. package/docs/i18n.md +0 -220
  93. package/docs/index.md +0 -10
  94. package/docs/markup.md +0 -136
  95. package/docs/mixins.md +0 -176
  96. package/docs/ref.md +0 -77
  97. package/docs/router.md +0 -281
  98. package/docs/setup.md +0 -137
  99. package/docs/signals.md +0 -262
  100. package/docs/stores.md +0 -113
  101. package/docs/views.md +0 -356
  102. package/notes/atomic.md +0 -452
  103. package/notes/elimination.md +0 -33
  104. package/notes/observable.md +0 -180
  105. package/notes/scratch.md +0 -565
  106. package/notes/splitting.md +0 -5
  107. package/notes/views.md +0 -195
  108. package/vite.config.js +0 -22
  109. /package/dist/core/{hooks.test.d.ts → markup/html.test.d.ts} +0 -0
  110. /package/dist/core/{ref.test.d.ts → markup/utils.test.d.ts} +0 -0
  111. /package/dist/router/{router.utils.test.d.ts → matcher.test.d.ts} +0 -0
  112. /package/dist/{typeChecking.test.d.ts → router/router.test.d.ts} +0 -0
@@ -0,0 +1,354 @@
1
+ //#region src/utils.ts
2
+ var e = 0;
3
+ function t() {
4
+ return (e++).toString(36);
5
+ }
6
+ function n(e, t) {
7
+ let n = {};
8
+ for (let r in t) e.includes(r) || (n[r] = t[r]);
9
+ return n;
10
+ }
11
+ function r(e, t) {
12
+ if (!e) throw TypeError(t);
13
+ }
14
+ function i(e) {
15
+ return Array.isArray(e);
16
+ }
17
+ function a(e) {
18
+ return typeof e == "string";
19
+ }
20
+ function o(e) {
21
+ return typeof e == "function" && !s(e);
22
+ }
23
+ function s(e) {
24
+ return /^\s*class\s+/.test(String(e));
25
+ }
26
+ function c(e) {
27
+ return typeof e == "number" && !isNaN(e);
28
+ }
29
+ function l(e) {
30
+ return typeof e == "object" && !!e && !i(e);
31
+ }
32
+ //#endregion
33
+ //#region src/core/signals.ts
34
+ var u = /* @__PURE__ */ function(e) {
35
+ return e[e.None = 0] = "None", e[e.Mutable = 1] = "Mutable", e[e.Watching = 2] = "Watching", e[e.RecursedCheck = 4] = "RecursedCheck", e[e.Recursed = 8] = "Recursed", e[e.Dirty = 16] = "Dirty", e[e.Pending = 32] = "Pending", e;
36
+ }(u || {}), d = 0, f = 0, p = 0, m = 0, h, g = [];
37
+ function _(e, t, n) {
38
+ let r = t._depsTail;
39
+ if (r !== void 0 && r._dep === e) return;
40
+ let i = r === void 0 ? t._deps : r._nextDep;
41
+ if (i !== void 0 && i._dep === e) {
42
+ i._version = n, t._depsTail = i;
43
+ return;
44
+ }
45
+ let a = e._subsTail;
46
+ if (a !== void 0 && a._version === n && a._sub === t) return;
47
+ let o = t._depsTail = e._subsTail = {
48
+ _version: n,
49
+ _dep: e,
50
+ _sub: t,
51
+ _prevDep: r,
52
+ _nextDep: i,
53
+ _prevSub: a,
54
+ _nextSub: void 0
55
+ };
56
+ i !== void 0 && (i._prevDep = o), r === void 0 ? t._deps = o : r._nextDep = o, a === void 0 ? e._subs = o : a._nextSub = o;
57
+ }
58
+ function v(e) {
59
+ e._flags & u.Mutable ? e._depsTail !== void 0 && (e._depsTail = void 0, e._flags = u.Mutable | u.Dirty, j(e)) : L.call(e);
60
+ }
61
+ function y(e, t = e._sub) {
62
+ let n = e._dep, r = e._prevDep, i = e._nextDep, a = e._nextSub, o = e._prevSub;
63
+ return i === void 0 ? t._depsTail = r : i._prevDep = r, r === void 0 ? t._deps = i : r._nextDep = i, a === void 0 ? n._subsTail = o : a._prevSub = o, o === void 0 ? (n._subs = a) === void 0 && v(n) : o._nextSub = a, i;
64
+ }
65
+ function b(e) {
66
+ let t = m, n = t;
67
+ do
68
+ if (g[t++] = e, e._flags &= ~u.Watching, e = e._subs?._sub, e === void 0 || !(e._flags & u.Watching)) break;
69
+ while (!0);
70
+ for (m = t; n < --t;) {
71
+ let e = g[n];
72
+ g[n++] = g[t], g[t] = e;
73
+ }
74
+ }
75
+ function x(e) {
76
+ return e._depsTail === void 0 ? O(e) : D(e);
77
+ }
78
+ function S(e) {
79
+ let t = e._nextSub, n;
80
+ top: do {
81
+ let r = e._sub, i = r._flags;
82
+ if (i & (u.RecursedCheck | u.Recursed | u.Dirty | u.Pending) ? i & (u.RecursedCheck | u.Recursed) ? i & u.RecursedCheck ? !(i & (u.Dirty | u.Pending)) && T(e, r) ? (r._flags = i | (u.Recursed | u.Pending), i &= u.Mutable) : i = u.None : r._flags = i & ~u.Recursed | u.Pending : i = u.None : r._flags = i | u.Pending, i & u.Watching && b(r), i & u.Mutable) {
83
+ let i = r._subs;
84
+ if (i !== void 0) {
85
+ let r = (e = i)._nextSub;
86
+ r !== void 0 && (n = {
87
+ _value: t,
88
+ _prev: n
89
+ }, t = r);
90
+ continue;
91
+ }
92
+ }
93
+ if ((e = t) !== void 0) {
94
+ t = e._nextSub;
95
+ continue;
96
+ }
97
+ for (; n !== void 0;) if (e = n._value, n = n._prev, e !== void 0) {
98
+ t = e._nextSub;
99
+ continue top;
100
+ }
101
+ break;
102
+ } while (!0);
103
+ }
104
+ function C(e, t) {
105
+ let n, r = 0, i = !1;
106
+ top: do {
107
+ let a = e._dep, o = a._flags;
108
+ if (t._flags & u.Dirty) i = !0;
109
+ else if ((o & (u.Mutable | u.Dirty)) === (u.Mutable | u.Dirty)) {
110
+ if (x(a)) {
111
+ let e = a._subs;
112
+ e._nextSub !== void 0 && w(e), i = !0;
113
+ }
114
+ } else if ((o & (u.Mutable | u.Pending)) === (u.Mutable | u.Pending)) {
115
+ (e._nextSub !== void 0 || e._prevSub !== void 0) && (n = {
116
+ _value: e,
117
+ _prev: n
118
+ }), e = a._deps, t = a, ++r;
119
+ continue;
120
+ }
121
+ if (!i) {
122
+ let t = e._nextDep;
123
+ if (t !== void 0) {
124
+ e = t;
125
+ continue;
126
+ }
127
+ }
128
+ for (; r--;) {
129
+ let r = t._subs, a = r._nextSub !== void 0;
130
+ if (a ? (e = n._value, n = n._prev) : e = r, i) {
131
+ if (x(t)) {
132
+ a && w(r), t = e._sub;
133
+ continue;
134
+ }
135
+ i = !1;
136
+ } else t._flags &= ~u.Pending;
137
+ t = e._sub;
138
+ let o = e._nextDep;
139
+ if (o !== void 0) {
140
+ e = o;
141
+ continue top;
142
+ }
143
+ }
144
+ return i;
145
+ } while (!0);
146
+ }
147
+ function w(e) {
148
+ do {
149
+ let t = e._sub, n = t._flags;
150
+ (n & (u.Pending | u.Dirty)) === u.Pending && (t._flags = n | u.Dirty, (n & (u.Watching | u.RecursedCheck)) === u.Watching && b(t));
151
+ } while ((e = e._nextSub) !== void 0);
152
+ }
153
+ function T(e, t) {
154
+ let n = t._depsTail;
155
+ for (; n !== void 0;) {
156
+ if (n === e) return !0;
157
+ n = n._prevDep;
158
+ }
159
+ return !1;
160
+ }
161
+ function E(e) {
162
+ let t = h;
163
+ return h = e, t;
164
+ }
165
+ function D(e) {
166
+ ++d, e._depsTail = void 0, e._flags = u.Mutable | u.RecursedCheck;
167
+ let t = E(e);
168
+ try {
169
+ let t = e._value;
170
+ return t !== (e._value = e._getter(t));
171
+ } finally {
172
+ h = t, e._flags &= ~u.RecursedCheck, j(e);
173
+ }
174
+ }
175
+ function O(e) {
176
+ return e._flags = u.Mutable, e._currentValue !== (e._currentValue = e._pendingValue);
177
+ }
178
+ function k(e) {
179
+ let t = e._flags;
180
+ if (t & u.Dirty || t & u.Pending && C(e._deps, e)) {
181
+ ++d, e._depsTail = void 0, e._flags = u.Watching | u.RecursedCheck;
182
+ let t = E(e);
183
+ try {
184
+ e._cleanup?.(), e._cleanup = void 0;
185
+ let t = e._fn();
186
+ o(t) && (e._cleanup = t);
187
+ } finally {
188
+ h = t, e._flags &= ~u.RecursedCheck, j(e);
189
+ }
190
+ } else e._flags = u.Watching;
191
+ }
192
+ function A() {
193
+ try {
194
+ for (; p < m;) {
195
+ let e = g[p];
196
+ g[p++] = void 0, k(e);
197
+ }
198
+ } finally {
199
+ for (; p < m;) {
200
+ let e = g[p];
201
+ g[p++] = void 0, e._flags |= u.Watching | u.Recursed;
202
+ }
203
+ p = 0, m = 0;
204
+ }
205
+ }
206
+ function j(e) {
207
+ let t = e._depsTail, n = t === void 0 ? e._deps : t._nextDep;
208
+ for (; n !== void 0;) n = y(n, e);
209
+ }
210
+ function M(e, t) {
211
+ return o(e) ? H(() => e(t)) : e;
212
+ }
213
+ function N() {
214
+ let e = this._flags;
215
+ if (e & u.Dirty || e & u.Pending && (C(this._deps, this) || (this._flags = e & ~u.Pending, !1))) {
216
+ if (D(this)) {
217
+ let e = this._subs;
218
+ e !== void 0 && w(e);
219
+ }
220
+ } else if (!e) {
221
+ this._flags = u.Mutable | u.RecursedCheck;
222
+ let e = E(this);
223
+ try {
224
+ this._value = V(this._getter());
225
+ } finally {
226
+ h = e, this._flags &= ~u.RecursedCheck;
227
+ }
228
+ }
229
+ let t = h;
230
+ return t !== void 0 && _(this, t, d), this._value;
231
+ }
232
+ function P(e) {
233
+ let t = M(e, this._value);
234
+ if (this._value !== t) {
235
+ this._value = t, this._flags &= ~(u.Dirty | u.Pending);
236
+ let e = this._subs;
237
+ for (; e !== void 0;) {
238
+ let t = e._sub, n = t._flags;
239
+ (n & (u.Dirty | u.Pending)) === 0 && (t._flags = n | u.Dirty, b(t)), e = e._nextSub;
240
+ }
241
+ f || A();
242
+ }
243
+ return t;
244
+ }
245
+ function F() {
246
+ if (this._flags & u.Dirty && O(this)) {
247
+ let e = this._subs;
248
+ e !== void 0 && w(e);
249
+ }
250
+ let e = h;
251
+ for (; e !== void 0;) {
252
+ if (e._flags & (u.Mutable | u.Watching)) {
253
+ _(this, e, d);
254
+ break;
255
+ }
256
+ e = e._subs?._sub;
257
+ }
258
+ return this._currentValue;
259
+ }
260
+ function I(e) {
261
+ let t = M(e, this._pendingValue);
262
+ if (this._pendingValue !== (this._pendingValue = t)) {
263
+ this._flags = u.Mutable | u.Dirty;
264
+ let e = this._subs;
265
+ e !== void 0 && (S(e), f || A());
266
+ }
267
+ }
268
+ function L() {
269
+ this._depsTail = void 0, this._flags = u.None, j(this);
270
+ let e = this._subs;
271
+ e !== void 0 && y(e), this._cleanup?.(), this._cleanup = void 0;
272
+ }
273
+ function R(e) {
274
+ if (o(e)) {
275
+ let t = {
276
+ _value: void 0,
277
+ _subs: void 0,
278
+ _subsTail: void 0,
279
+ _deps: void 0,
280
+ _depsTail: void 0,
281
+ _flags: u.None,
282
+ _getter: e
283
+ };
284
+ return [N.bind(t), P.bind(t)];
285
+ } else {
286
+ let t = {
287
+ _currentValue: e,
288
+ _pendingValue: e,
289
+ _subs: void 0,
290
+ _subsTail: void 0,
291
+ _flags: u.Mutable
292
+ };
293
+ return [F.bind(t), I.bind(t)];
294
+ }
295
+ }
296
+ function z(e) {
297
+ return N.bind({
298
+ _value: void 0,
299
+ _subs: void 0,
300
+ _subsTail: void 0,
301
+ _deps: void 0,
302
+ _depsTail: void 0,
303
+ _flags: u.None,
304
+ _getter: e
305
+ });
306
+ }
307
+ function B(e) {
308
+ let t = {
309
+ _fn: e,
310
+ _cleanup: void 0,
311
+ _subs: void 0,
312
+ _subsTail: void 0,
313
+ _deps: void 0,
314
+ _depsTail: void 0,
315
+ _flags: u.Watching | u.RecursedCheck
316
+ }, n = E(t);
317
+ n !== void 0 && _(t, n, 0);
318
+ try {
319
+ let e = t._fn();
320
+ o(e) && (t._cleanup = e);
321
+ } finally {
322
+ h = n, t._flags &= ~u.RecursedCheck;
323
+ }
324
+ return L.bind(t);
325
+ }
326
+ function V(e) {
327
+ return o(e) ? e() : e;
328
+ }
329
+ function H(e) {
330
+ let t = E(void 0);
331
+ try {
332
+ return V(e);
333
+ } finally {
334
+ E(t);
335
+ }
336
+ }
337
+ function U(e) {
338
+ ++f;
339
+ try {
340
+ e();
341
+ } finally {
342
+ --f || A();
343
+ }
344
+ }
345
+ function W(e, t) {
346
+ return B(() => {
347
+ let n = e();
348
+ H(() => t(n));
349
+ });
350
+ }
351
+ //#endregion
352
+ export { H as a, r as c, c as d, l as f, t as h, B as i, i as l, n as m, z as n, W as o, a as p, R as r, V as s, U as t, o as u };
353
+
354
+ //# sourceMappingURL=signals-CMJPGr_M.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals-CMJPGr_M.js","names":[],"sources":["../src/utils.ts","../src/core/signals.ts"],"sourcesContent":["/*=============================*\\\n|| ID Generator ||\n\\*=============================*/\n\nlet lastId = 0;\nexport function uniqueId() {\n return (lastId++).toString(36);\n}\n\n/*=============================*\\\n|| Object Utils ||\n\\*=============================*/\n\n/**\n * Returns a new object without the specified keys.\n * If called without object, returns a function that takes an object\n * and returns a version with the original keys omitted.\n *\n * @param keys - An array of keys to omit.\n * @param object - An object to clone without the omitted keys.\n */\nexport function omit<O extends Record<any, any>>(keys: (keyof O)[], object: O): Record<any, any> {\n const newObject: Record<any, any> = {};\n\n for (const key in object) {\n if (!keys.includes(key)) {\n newObject[key] = object[key];\n }\n }\n\n return newObject;\n}\n\n/*=============================*\\\n|| Type Checking ||\n\\*=============================*/\n\n/**\n * Throws a TypeError unless `condition` is truthy.\n *\n * @param value - Value whose truthiness is in question.\n * @param errorMessage - Optional message for the thrown TypeError.\n */\nexport function assert<T = any>(value: T, errorMessage: string): asserts value is NonNullable<T> {\n if (!value) throw new TypeError(errorMessage);\n}\n\n/**\n * Returns true if `value` is an array.\n */\nexport function isArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value);\n}\n\n/**\n * Returns true when `value` is an array and `check` returns true for every item.\n *\n * @param check - Function to check items against.\n * @param value - A possible array.\n */\nexport function isArrayOf<T>(check: (item: unknown) => boolean, value: unknown): value is T[];\nexport function isArrayOf<T>(check: (item: unknown) => boolean): (value: unknown) => value is T[];\n\nexport function isArrayOf<T>(check: (item: unknown) => boolean, value?: unknown) {\n if (value) {\n return isArray(value) && value.every((item) => check(item));\n } else {\n return (value: unknown) => isArrayOf<T>(check, value);\n }\n}\n\n/**\n * Returns true if `value` is a string.\n */\nexport function isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n\n/**\n * Returns true if `value` is a function (but not a class).\n */\nexport function isFunction<T = (...args: unknown[]) => unknown>(value: unknown): value is T {\n return typeof value === \"function\" && !isClass(value);\n}\n\nexport function isClass(value: unknown) {\n return /^\\s*class\\s+/.test(String(value));\n}\n\n/**\n * Returns true if `value` is a number.\n */\nexport function isNumber(value: unknown): value is number {\n return typeof value === \"number\" && !isNaN(value);\n}\n\n/**\n * Returns `true` if `value` is an instance of `constructor`.\n *\n * @param constructor - The constructor `value` must be an instance of.\n * @param value - A value that may be an instance of `constructor`.\n */\nexport function isInstanceOf<T extends Function>(constructor: T, value: unknown): value is T;\nexport function isInstanceOf<T extends Function>(constructor: T): (value: unknown) => value is T;\n\nexport function isInstanceOf<T extends Function>(constructor: T, value?: unknown) {\n if (value) {\n return value instanceof constructor;\n } else {\n return (value: unknown) => isInstanceOf(constructor, value);\n }\n}\n\n/**\n * Returns true if `value` is a JavaScript Promise.\n */\nexport function isPromise<T = unknown>(value: unknown): value is Promise<T> {\n return value instanceof Promise;\n}\n\n/**\n * Returns true if `value` is a plain JavaScript object.\n */\nexport function isObject<T = Record<string | number | symbol, unknown>>(value: unknown): value is T {\n return value != null && typeof value === \"object\" && !isArray(value);\n}\n","import { isFunction } from \"../utils.js\";\n\ninterface ReactiveNode {\n _deps?: Link;\n _depsTail?: Link;\n _subs?: Link;\n _subsTail?: Link;\n _flags: ReactiveFlags;\n}\n\ninterface EffectNode extends ReactiveNode {\n _fn(): void | (() => void);\n _cleanup?: () => void;\n}\n\ninterface ComputedNode<T = any> extends ReactiveNode {\n _value: T | undefined;\n _getter: (previousValue?: T) => T;\n}\n\ninterface ValueNode<T = any> extends ReactiveNode {\n _currentValue: T;\n _pendingValue: T;\n}\n\ninterface Link {\n _version: number;\n _dep: ReactiveNode;\n _sub: ReactiveNode;\n _prevSub: Link | undefined;\n _nextSub: Link | undefined;\n _prevDep: Link | undefined;\n _nextDep: Link | undefined;\n}\n\ninterface Stack<T> {\n _value: T;\n _prev: Stack<T> | undefined;\n}\n\n/*==================================*\\\n|| Signal Internals ||\n\\*==================================*/\n\nconst enum ReactiveFlags {\n None = 0,\n Mutable = 1,\n Watching = 2,\n RecursedCheck = 4,\n Recursed = 8,\n Dirty = 16,\n Pending = 32,\n}\n\nlet cycle = 0;\nlet batchDepth = 0;\nlet notifyIndex = 0;\nlet queuedLength = 0;\nlet activeSub: ReactiveNode | undefined;\n\nconst queued: (EffectNode | undefined)[] = [];\n\nfunction link(dep: ReactiveNode, sub: ReactiveNode, version: number): void {\n const prevDep = sub._depsTail;\n if (prevDep !== undefined && prevDep._dep === dep) {\n return;\n }\n const nextDep = prevDep !== undefined ? prevDep._nextDep : sub._deps;\n if (nextDep !== undefined && nextDep._dep === dep) {\n nextDep._version = version;\n sub._depsTail = nextDep;\n return;\n }\n const prevSub = dep._subsTail;\n if (prevSub !== undefined && prevSub._version === version && prevSub._sub === sub) {\n return;\n }\n const newLink =\n (sub._depsTail =\n dep._subsTail =\n {\n _version: version,\n _dep: dep,\n _sub: sub,\n _prevDep: prevDep,\n _nextDep: nextDep,\n _prevSub: prevSub,\n _nextSub: undefined,\n });\n if (nextDep !== undefined) {\n nextDep._prevDep = newLink;\n }\n if (prevDep !== undefined) {\n prevDep._nextDep = newLink;\n } else {\n sub._deps = newLink;\n }\n if (prevSub !== undefined) {\n prevSub._nextSub = newLink;\n } else {\n dep._subs = newLink;\n }\n}\n\nfunction unwatched(node: ReactiveNode): void {\n if (!(node._flags & ReactiveFlags.Mutable)) {\n effectCleanup.call(node);\n } else if (node._depsTail !== undefined) {\n node._depsTail = undefined;\n node._flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;\n purgeDeps(node);\n }\n}\n\nfunction unlink(link: Link, sub = link._sub): Link | undefined {\n const dep = link._dep;\n const prevDep = link._prevDep;\n const nextDep = link._nextDep;\n const nextSub = link._nextSub;\n const prevSub = link._prevSub;\n if (nextDep !== undefined) {\n nextDep._prevDep = prevDep;\n } else {\n sub._depsTail = prevDep;\n }\n if (prevDep !== undefined) {\n prevDep._nextDep = nextDep;\n } else {\n sub._deps = nextDep;\n }\n if (nextSub !== undefined) {\n nextSub._prevSub = prevSub;\n } else {\n dep._subsTail = prevSub;\n }\n if (prevSub !== undefined) {\n prevSub._nextSub = nextSub;\n } else if ((dep._subs = nextSub) === undefined) {\n unwatched(dep);\n }\n return nextDep;\n}\n\nfunction notify(effect: EffectNode): void {\n let insertIndex = queuedLength;\n let firstInsertedIndex = insertIndex;\n\n do {\n queued[insertIndex++] = effect;\n effect._flags &= ~ReactiveFlags.Watching;\n effect = effect._subs?._sub as EffectNode;\n if (effect === undefined || !(effect._flags & ReactiveFlags.Watching)) {\n break;\n }\n } while (true);\n\n queuedLength = insertIndex;\n\n while (firstInsertedIndex < --insertIndex) {\n const left = queued[firstInsertedIndex];\n queued[firstInsertedIndex++] = queued[insertIndex];\n queued[insertIndex] = left;\n }\n}\n\nfunction update(node: ReactiveNode): boolean {\n if (node._depsTail !== undefined) {\n return updateComputed(node as ComputedNode);\n } else {\n return updateValue(node as ValueNode);\n }\n}\n\nfunction propagate(link: Link): void {\n let next = link._nextSub;\n let stack: Stack<Link | undefined> | undefined;\n\n top: do {\n const sub = link._sub;\n let flags = sub._flags;\n\n if (\n !(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed | ReactiveFlags.Dirty | ReactiveFlags.Pending))\n ) {\n sub._flags = flags | ReactiveFlags.Pending;\n } else if (!(flags & (ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))) {\n flags = ReactiveFlags.None;\n } else if (!(flags & ReactiveFlags.RecursedCheck)) {\n sub._flags = (flags & ~ReactiveFlags.Recursed) | ReactiveFlags.Pending;\n } else if (!(flags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) && isValidLink(link, sub)) {\n sub._flags = flags | (ReactiveFlags.Recursed | ReactiveFlags.Pending);\n flags &= ReactiveFlags.Mutable;\n } else {\n flags = ReactiveFlags.None;\n }\n\n if (flags & ReactiveFlags.Watching) {\n notify(sub as EffectNode);\n }\n\n if (flags & ReactiveFlags.Mutable) {\n const subSubs = sub._subs;\n if (subSubs !== undefined) {\n const nextSub = (link = subSubs)._nextSub;\n if (nextSub !== undefined) {\n stack = { _value: next, _prev: stack };\n next = nextSub;\n }\n continue;\n }\n }\n\n if ((link = next!) !== undefined) {\n next = link._nextSub;\n continue;\n }\n\n while (stack !== undefined) {\n link = stack._value!;\n stack = stack._prev;\n if (link !== undefined) {\n next = link._nextSub;\n continue top;\n }\n }\n\n break;\n } while (true);\n}\n\nfunction checkDirty(link: Link, sub: ReactiveNode): boolean {\n let stack: Stack<Link> | undefined;\n let checkDepth = 0;\n let dirty = false;\n\n top: do {\n const dep = link._dep;\n const flags = dep._flags;\n\n if (sub._flags & ReactiveFlags.Dirty) {\n dirty = true;\n } else if (\n (flags & (ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep)) {\n const subs = dep._subs!;\n if (subs._nextSub !== undefined) {\n shallowPropagate(subs);\n }\n dirty = true;\n }\n } else if (\n (flags & (ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link._nextSub !== undefined || link._prevSub !== undefined) {\n stack = { _value: link, _prev: stack };\n }\n link = dep._deps!;\n sub = dep;\n ++checkDepth;\n continue;\n }\n\n if (!dirty) {\n const nextDep = link._nextDep;\n if (nextDep !== undefined) {\n link = nextDep;\n continue;\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub._subs!;\n const hasMultipleSubs = firstSub._nextSub !== undefined;\n if (hasMultipleSubs) {\n link = stack!._value;\n stack = stack!._prev;\n } else {\n link = firstSub;\n }\n if (dirty) {\n if (update(sub)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub);\n }\n sub = link._sub;\n continue;\n }\n dirty = false;\n } else {\n sub._flags &= ~ReactiveFlags.Pending;\n }\n sub = link._sub;\n const nextDep = link._nextDep;\n if (nextDep !== undefined) {\n link = nextDep;\n continue top;\n }\n }\n\n return dirty;\n } while (true);\n}\n\nfunction shallowPropagate(link: Link): void {\n do {\n const sub = link._sub;\n const flags = sub._flags;\n if ((flags & (ReactiveFlags.Pending | ReactiveFlags.Dirty)) === ReactiveFlags.Pending) {\n sub._flags = flags | ReactiveFlags.Dirty;\n if ((flags & (ReactiveFlags.Watching | ReactiveFlags.RecursedCheck)) === ReactiveFlags.Watching) {\n notify(sub as EffectNode);\n }\n }\n } while ((link = link._nextSub!) !== undefined);\n}\n\nfunction isValidLink(checkLink: Link, sub: ReactiveNode): boolean {\n let link = sub._depsTail;\n while (link !== undefined) {\n if (link === checkLink) {\n return true;\n }\n link = link._prevDep;\n }\n return false;\n}\n\nfunction setActiveSub(sub?: ReactiveNode) {\n const prevSub = activeSub;\n activeSub = sub;\n return prevSub;\n}\n\nfunction updateComputed(c: ComputedNode): boolean {\n ++cycle;\n c._depsTail = undefined;\n c._flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(c);\n try {\n const oldValue = c._value;\n return oldValue !== (c._value = c._getter(oldValue));\n } finally {\n activeSub = prevSub;\n c._flags &= ~ReactiveFlags.RecursedCheck;\n purgeDeps(c);\n }\n}\n\nfunction updateValue(v: ValueNode): boolean {\n v._flags = ReactiveFlags.Mutable;\n return v._currentValue !== (v._currentValue = v._pendingValue);\n}\n\nfunction run(e: EffectNode): void {\n const flags = e._flags;\n if (flags & ReactiveFlags.Dirty || (flags & ReactiveFlags.Pending && checkDirty(e._deps!, e))) {\n ++cycle;\n e._depsTail = undefined;\n e._flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(e);\n try {\n e._cleanup?.();\n e._cleanup = undefined;\n const result = e._fn();\n if (isFunction(result)) e._cleanup = result;\n } finally {\n activeSub = prevSub;\n e._flags &= ~ReactiveFlags.RecursedCheck;\n purgeDeps(e);\n }\n } else {\n e._flags = ReactiveFlags.Watching;\n }\n}\n\nfunction flush(): void {\n try {\n while (notifyIndex < queuedLength) {\n const effect = queued[notifyIndex]!;\n queued[notifyIndex++] = undefined;\n run(effect);\n }\n } finally {\n while (notifyIndex < queuedLength) {\n const effect = queued[notifyIndex]!;\n queued[notifyIndex++] = undefined;\n effect._flags |= ReactiveFlags.Watching | ReactiveFlags.Recursed;\n }\n notifyIndex = 0;\n queuedLength = 0;\n }\n}\n\nfunction purgeDeps(sub: ReactiveNode) {\n const depsTail = sub._depsTail;\n let dep = depsTail !== undefined ? depsTail._nextDep : sub._deps;\n while (dep !== undefined) {\n dep = unlink(dep, sub);\n }\n}\n\n/*==================================*\\\n|| API Implementation ||\n\\*==================================*/\n\nfunction resolveValue<T>(next: SetterAction<T>, current: T): T {\n if (isFunction(next)) return peek(() => next(current)) as T;\n return next as T;\n}\n\nfunction computedGetter(this: ComputedNode) {\n const flags = this._flags;\n if (\n flags & ReactiveFlags.Dirty ||\n (flags & ReactiveFlags.Pending &&\n (checkDirty(this._deps!, this) || ((this._flags = flags & ~ReactiveFlags.Pending), false)))\n ) {\n if (updateComputed(this)) {\n const subs = this._subs;\n if (subs !== undefined) {\n shallowPropagate(subs);\n }\n }\n } else if (!flags) {\n this._flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;\n const prevSub = setActiveSub(this);\n try {\n this._value = unwrap(this._getter());\n } finally {\n activeSub = prevSub;\n this._flags &= ~ReactiveFlags.RecursedCheck;\n }\n }\n const sub = activeSub;\n if (sub !== undefined) {\n link(this, sub, cycle);\n }\n return this._value!;\n}\n\nfunction computedSetter(this: ComputedNode, next: SetterAction<any>) {\n const value = resolveValue(next, this._value);\n if (this._value !== value) {\n this._value = value;\n\n // Clear Dirty and Pending so _computedGetter skips updateComputed\n this._flags &= ~(ReactiveFlags.Dirty | ReactiveFlags.Pending);\n\n // Manually push the Dirty flag to all subscribers\n let link = this._subs;\n while (link !== undefined) {\n const sub = link._sub;\n const subFlags = sub._flags;\n\n // Only modify and notify if it isn't already queued for an update\n if ((subFlags & (ReactiveFlags.Dirty | ReactiveFlags.Pending)) === 0) {\n // Force the node to be Dirty so it bypasses checkDirty() upon flush\n sub._flags = subFlags | ReactiveFlags.Dirty;\n notify(sub as EffectNode);\n }\n\n link = link._nextSub;\n }\n\n // Trigger queued effects\n if (!batchDepth) {\n flush();\n }\n }\n return value;\n}\n\nfunction computedAccessor<T>(this: ComputedNode<T>, ...next: [SetterAction<T>]): T {\n if (next.length) {\n return computedSetter.call(this, next[0]) as T;\n } else {\n return computedGetter.call(this) as T;\n }\n}\n\nfunction valueGetter<T>(this: ValueNode<T>): T {\n if (this._flags & ReactiveFlags.Dirty) {\n if (updateValue(this)) {\n const subs = this._subs;\n if (subs !== undefined) {\n shallowPropagate(subs);\n }\n }\n }\n let sub = activeSub;\n while (sub !== undefined) {\n if (sub._flags & (ReactiveFlags.Mutable | ReactiveFlags.Watching)) {\n link(this, sub, cycle);\n break;\n }\n sub = sub._subs?._sub;\n }\n return this._currentValue;\n}\n\nfunction valueSetter<T>(this: ValueNode<T>, next: SetterAction<T>): void {\n const value = resolveValue(next, this._pendingValue);\n if (this._pendingValue !== (this._pendingValue = value)) {\n this._flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;\n const subs = this._subs;\n if (subs !== undefined) {\n propagate(subs);\n if (!batchDepth) {\n flush();\n }\n }\n }\n}\n\nfunction valueAccessor<T>(this: ValueNode<T>, ...args: [SetterAction<T>]): T | void {\n if (args.length) {\n return valueSetter.call(this, args[0]);\n } else {\n return valueGetter.call(this) as T;\n }\n}\n\nfunction effectCleanup(this: ReactiveNode): void {\n this._depsTail = undefined;\n this._flags = ReactiveFlags.None;\n purgeDeps(this);\n const sub = this._subs;\n if (sub !== undefined) {\n unlink(sub);\n }\n (this as EffectNode)._cleanup?.();\n (this as EffectNode)._cleanup = undefined;\n}\n\n/*==================================*\\\n|| Public API ||\n\\*==================================*/\n\n/**\n * Returns the currently held value. Registers the state as a dependency when called within a tracking context.\n */\nexport type Getter<T> = () => T;\n\n/**\n * A value that may be a static value or a getter function.\n * Can be converted to a plain value with `unwrap`.\n */\nexport type MaybeGetter<T> = T | Getter<T>;\n\n/**\n * Updates the value of an atom. Takes a new plain value, or an update function to compute one.\n */\nexport type Setter<T> = (next: SetterAction<T>) => T;\nexport type SetterAction<T> = T | ((prev: T) => T);\n\n/**\n * A getter and setter pair, as returned from `createAtom`.\n */\nexport type AtomAccessors<T> = [Getter<T>, Setter<T>];\n\n/**\n * Creates a new atom with a default `undefined` value.\n * Returns a `[getter, setter]` function tuple.\n *\n * @example\n * const [getValue, setValue] = createAtom();\n */\nexport function createAtom<T>(): AtomAccessors<T | undefined>;\n\n/**\n * Creates a new atom with a value computed from an existing getter.\n * This is usually used to create a 'settable' getter, in which you can store\n * a temporary value until it gets overwritten by a _real_ update.\n *\n * @example\n * const [getValue, setValue] = createAtom(\"\");\n * const [getInputValue, setInputValue] = createAtom(getValue);\n *\n * setInputValue(\"temporary\");\n * getValue(\"\");\n * getInputValue(); // \"temporary\"\n *\n * setValue(\"overwritten\");\n * getValue(\"overwritten\");\n * getInputValue(); // \"overwritten\"\n */\nexport function createAtom<T>(compute: Getter<T>): AtomAccessors<T>;\n\n/**\n * Creates a new atom with an initial value.\n * Returns a `[getter, setter]` function tuple.\n *\n * @example\n * const [getCount, setCount] = createAtom(5);\n */\nexport function createAtom<T>(initialValue: T): AtomAccessors<T>;\n\nexport function createAtom<T>(value?: T) {\n if (isFunction<Getter<T>>(value)) {\n const node: ComputedNode<T> = {\n _value: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.None,\n _getter: value as (previousValue?: T | undefined) => T,\n };\n return [computedGetter.bind(node), computedSetter.bind(node)];\n } else {\n const node: ValueNode<T> = {\n _currentValue: value as T,\n _pendingValue: value as T,\n _subs: undefined,\n _subsTail: undefined,\n _flags: ReactiveFlags.Mutable,\n };\n return [valueGetter.bind(node), valueSetter.bind(node)];\n }\n}\n\nexport function compose<T>(getter: (previousValue?: T) => Getter<T> | T): Getter<T> {\n return computedGetter.bind({\n _value: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.None,\n _getter: getter as (previousValue?: unknown) => unknown,\n }) as () => T;\n}\n\nexport function createEffect(fn: () => void): () => void {\n const e: EffectNode = {\n _fn: fn,\n _cleanup: undefined,\n _subs: undefined,\n _subsTail: undefined,\n _deps: undefined,\n _depsTail: undefined,\n _flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck,\n };\n const prevSub = setActiveSub(e);\n if (prevSub !== undefined) {\n link(e, prevSub, 0);\n }\n try {\n const result = e._fn();\n if (isFunction(result)) e._cleanup = result;\n } finally {\n activeSub = prevSub;\n e._flags &= ~ReactiveFlags.RecursedCheck;\n }\n return effectCleanup.bind(e);\n}\n\n/**\n * Unwraps a `MaybeGetter<T>` into a plain `T`.\n * Tracks the value if it is a getter.\n * Use the non-tracking `peek` if you're being stealthy.\n */\nexport function unwrap<T>(value: T | Getter<T>): T {\n if (isFunction<Getter<T>>(value)) {\n return value();\n } else {\n return value;\n }\n}\n\n/**\n * Unwraps a `MaybeGetter<T>` into a plain `T`. Will _not_ track if the value is a getter.\n */\nexport function peek<T>(value: T | Getter<T>): T {\n const prevSub = setActiveSub(undefined);\n try {\n return unwrap(value);\n } finally {\n setActiveSub(prevSub);\n }\n}\n\n/**\n * Groups several signal changes into a single transaction.\n * Suspends effects until `callback` finishes, then runs all updates at once.\n */\nexport function batch(callback: () => void): void {\n ++batchDepth;\n try {\n callback();\n } finally {\n if (!--batchDepth) {\n flush();\n }\n }\n}\n\nexport function subscribe<T>(target: Getter<T>, fn: (value: T) => any): () => void {\n return createEffect(() => {\n const value = target();\n peek(() => fn(value));\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ import { Context } from "../core/context.js";
2
+ import { DollaPlugin } from "../core/root.js";
3
+ import { type Getter } from "../core/signals.js";
4
+ /**
5
+ * A JSON object of translated strings. Values can be string templates or nested objects.
6
+ */
7
+ export interface LocalizedStrings extends Record<string, string | LocalizedStrings> {
8
+ }
9
+ /**
10
+ * A function that returns an object of localized strings.
11
+ */
12
+ export type TranslationFetchFn = () => LocalizedStrings | Promise<LocalizedStrings>;
13
+ export type TOptions = {
14
+ /**
15
+ *
16
+ */
17
+ count?: Getter<number> | number;
18
+ /**
19
+ *
20
+ */
21
+ context?: Getter<string> | string;
22
+ [value: string]: Getter<any> | any;
23
+ };
24
+ export type LookupFn = (selector: string, options?: TOptions) => string;
25
+ export type Formatter = (locale: string, value: any, options: Record<string, any>) => string;
26
+ type BuiltInFormatters = {
27
+ number: [number | bigint, Intl.NumberFormatOptions?];
28
+ datetime: [Date, Intl.DateTimeFormatOptions?];
29
+ list: [Iterable<string>, Intl.ListFormatOptions?];
30
+ };
31
+ export interface Translator {
32
+ /**
33
+ * An array of locale names for all translations the app supports.
34
+ */
35
+ supportedLocales: string[];
36
+ /**
37
+ * A Readable containing the currently loaded locale.
38
+ */
39
+ currentLocale: Getter<string>;
40
+ /**
41
+ * Updates the locale, fetching any translation files as required.
42
+ * Returns a promise that resolves when the new locale is applied.
43
+ *
44
+ * If `name` is undefined the library will try to match the browser language automatically.
45
+ */
46
+ setLocale(name?: string): Promise<void>;
47
+ /**
48
+ * Returns a Readable of the value at `key`.
49
+
50
+ * @param selector - Key to the translated value.
51
+ * @param options - A map of `{{placeholder}}` names and the values to replace them with.
52
+ *
53
+ * @example
54
+ * const value = t("your.key.here", { count: 5 });
55
+ */
56
+ t(selector: string, options?: TOptions): Getter<string>;
57
+ format<K extends keyof BuiltInFormatters, V extends BuiltInFormatters[K][0], O extends BuiltInFormatters[K][1]>(name: K, value: Getter<V> | V, options?: O): Getter<string>;
58
+ format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;
59
+ }
60
+ export interface TranslatorOptions {
61
+ translations: Record<string, LocalizedStrings | TranslationFetchFn>;
62
+ /**
63
+ * Default locale to load on startup. The translator will try to match the user's browser language if left undefined.
64
+ */
65
+ locale?: string;
66
+ formatters?: Record<string, Formatter>;
67
+ }
68
+ export declare function createTranslatePlugin(options: TranslatorOptions): DollaPlugin;
69
+ export declare function getTranslate(context: Context): Translator;
70
+ /**
71
+ * Compiles an object of translated strings into a set of function templates.
72
+ */
73
+ export declare function compile(strings: {
74
+ [key: string]: any;
75
+ }, path?: string[]): [string, CompiledTemplate][];
76
+ export type TemplateSegmentFn = (options: Record<string, any> | undefined, formatters: Map<string, Formatter>, locale: string) => string;
77
+ export type CompiledTemplate = TemplateSegmentFn[];
78
+ /**
79
+ * Parse a string template into an array of functions that will produce each piece of the output when called.
80
+ */
81
+ export declare function parseTemplate(template: string): CompiledTemplate;
82
+ export {};
@@ -0,0 +1,125 @@
1
+ import { n as e, r as t, s as n, u as r } from "./signals-CMJPGr_M.js";
2
+ //#region src/translate/index.ts
3
+ var i = Symbol("Dolla.Translator");
4
+ function a(e) {
5
+ return async function(t) {
6
+ let n = s(e);
7
+ t[i] = n, await n.setLocale(e.locale);
8
+ };
9
+ }
10
+ function o(e) {
11
+ if (!e[i]) throw Error("Translate plugin isn't loaded.");
12
+ return e[i];
13
+ }
14
+ function s(r) {
15
+ let i = /* @__PURE__ */ new Map();
16
+ if (i.set("number", (e, t, n) => new Intl.NumberFormat(e, n).format(Number(t))), i.set("datetime", (e, t, n) => new Intl.DateTimeFormat(e, n).format(new Date(t))), i.set("list", (e, t, n) => new Intl.ListFormat(e, n).format(t)), r.formatters) for (let e in r.formatters) i.set(e, r.formatters[e]);
17
+ let a, [o, s] = t("en"), l = [...Object.keys(r.translations)];
18
+ async function u(e) {
19
+ let t;
20
+ if (e === void 0) {
21
+ let e = [];
22
+ if (typeof navigator < "u") {
23
+ let t = navigator;
24
+ t.languages?.length > 0 ? e.push(...t.languages) : t.language ? e.push(t.language) : t.browserLanguage ? e.push(t.browserLanguage) : t.userLanguage && e.push(t.userLanguage);
25
+ }
26
+ for (let n of e) if (n in r.translations) {
27
+ t = n;
28
+ break;
29
+ }
30
+ } else e in r.translations && (t = e);
31
+ if (t == null) {
32
+ let e = Object.keys(r.translations).at(0);
33
+ e && (t = e);
34
+ }
35
+ if (!t || !(t in r.translations)) throw Error(`Locale '${e}' has no translation.`);
36
+ a = await c(t, i, r.translations[t]), s(t);
37
+ }
38
+ function d(t, n) {
39
+ return e(() => (o(), a?.(t, n) ?? t));
40
+ }
41
+ function f(t, r, a) {
42
+ let s = i.get(t);
43
+ if (!s) throw Error(`Unknown format: ${t}`);
44
+ return e(() => s(o(), n(r), a ?? {}));
45
+ }
46
+ return {
47
+ supportedLocales: l,
48
+ currentLocale: o,
49
+ setLocale: u,
50
+ t: d,
51
+ format: f
52
+ };
53
+ }
54
+ async function c(e, t, i) {
55
+ let a = l(r(i) ? await i() : i), o = new Map(a);
56
+ return function(r, i) {
57
+ if (i && (i.context != null && (r += "_" + i.context), i.count != null)) if (i.ordinal) {
58
+ let t = `${r}_ordinal_(=${i.count})`;
59
+ o.has(t) ? r = t : r += "_ordinal_" + new Intl.PluralRules(e, { type: "ordinal" }).select(n(i.count));
60
+ } else {
61
+ let t = `${r}_(=${i.count})`;
62
+ o.has(t) ? r = t : r += "_" + new Intl.PluralRules(e).select(n(i.count));
63
+ }
64
+ let a = o.get(r);
65
+ if (!a) return r;
66
+ let s = "";
67
+ for (let n = 0; n < a.length; n++) s += a[n](i, t, e);
68
+ return s;
69
+ };
70
+ }
71
+ function l(e, t = []) {
72
+ let n = [];
73
+ for (let r in e) switch (typeof e[r]) {
74
+ case "string":
75
+ n.push([[...t, r].join("."), u(e[r])]);
76
+ break;
77
+ case "object":
78
+ n.push(...l(e[r], [...t, r]));
79
+ break;
80
+ default: throw Error(`Expected to find a string or object at ${[...t, r].join(".")}. Got: ${typeof e[r]}`);
81
+ }
82
+ return n;
83
+ }
84
+ function u(e) {
85
+ let t = e.split(/(\{\{.*?\}\})/g), r = [];
86
+ for (let e = 0; e < t.length; e++) {
87
+ let i = t[e];
88
+ if (i) if (i.startsWith("{{") && i.endsWith("}}")) {
89
+ let e = i.slice(2, -2).trim().split("|").map((e) => e.trim()), t = e[0], a = [];
90
+ for (let t = 1; t < e.length; t++) {
91
+ let n = e[t], r = n.match(/^([a-zA-Z0-9_]+)(?:\((.*)\))?$/);
92
+ if (r) {
93
+ let e = r[1], t = r[2], n = {};
94
+ if (t) {
95
+ let e = t.split(",");
96
+ for (let t = 0; t < e.length; t++) {
97
+ let r = e[t], i = r.indexOf(":");
98
+ i > -1 && (n[r.slice(0, i).trim()] = r.slice(i + 1).trim());
99
+ }
100
+ }
101
+ a.push({
102
+ name: e,
103
+ options: n
104
+ });
105
+ } else a.push({
106
+ name: n,
107
+ options: {}
108
+ });
109
+ }
110
+ r.push((e, r, i) => {
111
+ let o = e ? n(e[t]) : void 0;
112
+ for (let e = 0; e < a.length; e++) {
113
+ let t = a[e], n = r.get(t.name);
114
+ n && (o = n(i, o, t.options));
115
+ }
116
+ return o == null ? "" : String(o);
117
+ });
118
+ } else r.push(() => i);
119
+ }
120
+ return r;
121
+ }
122
+ //#endregion
123
+ export { l as compile, a as createTranslatePlugin, o as getTranslate, u as parseTemplate };
124
+
125
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","names":[],"sources":["../src/translate/index.ts"],"sourcesContent":["import { Context } from \"../core/context.js\";\nimport { DollaPlugin } from \"../core/root.js\";\nimport { unwrap, compose, createAtom, type Getter } from \"../core/signals.js\";\nimport { isFunction } from \"../utils.js\";\n\n// ----- Types ----- //\n\n/**\n * A JSON object of translated strings. Values can be string templates or nested objects.\n */\nexport interface LocalizedStrings extends Record<string, string | LocalizedStrings> {}\n\n/**\n * A function that returns an object of localized strings.\n */\nexport type TranslationFetchFn = () => LocalizedStrings | Promise<LocalizedStrings>;\n\nexport type TOptions = {\n /**\n *\n */\n count?: Getter<number> | number;\n\n /**\n *\n */\n context?: Getter<string> | string;\n\n [value: string]: Getter<any> | any;\n};\n\nexport type LookupFn = (selector: string, options?: TOptions) => string;\n\nexport type Formatter = (locale: string, value: any, options: Record<string, any>) => string;\n\ntype BuiltInFormatters = {\n number: [number | bigint, Intl.NumberFormatOptions?];\n datetime: [Date, Intl.DateTimeFormatOptions?];\n list: [Iterable<string>, Intl.ListFormatOptions?];\n};\n\nexport interface Translator {\n /**\n * An array of locale names for all translations the app supports.\n */\n supportedLocales: string[];\n\n /**\n * A Readable containing the currently loaded locale.\n */\n currentLocale: Getter<string>;\n\n /**\n * Updates the locale, fetching any translation files as required.\n * Returns a promise that resolves when the new locale is applied.\n *\n * If `name` is undefined the library will try to match the browser language automatically.\n */\n setLocale(name?: string): Promise<void>;\n\n /**\n * Returns a Readable of the value at `key`.\n\n * @param selector - Key to the translated value.\n * @param options - A map of `{{placeholder}}` names and the values to replace them with.\n *\n * @example\n * const value = t(\"your.key.here\", { count: 5 });\n */\n t(selector: string, options?: TOptions): Getter<string>;\n\n format<K extends keyof BuiltInFormatters, V extends BuiltInFormatters[K][0], O extends BuiltInFormatters[K][1]>(\n name: K,\n value: Getter<V> | V,\n options?: O,\n ): Getter<string>;\n\n format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;\n}\n\nexport interface TranslatorOptions {\n translations: Record<string, LocalizedStrings | TranslationFetchFn>;\n\n /**\n * Default locale to load on startup. The translator will try to match the user's browser language if left undefined.\n */\n locale?: string;\n\n formatters?: Record<string, Formatter>;\n}\n\nconst TRANSLATE = Symbol(\"Dolla.Translator\");\n\nexport function createTranslatePlugin(options: TranslatorOptions): DollaPlugin {\n return async function (context) {\n const translator = createTranslator(options);\n context[TRANSLATE] = translator;\n await translator.setLocale(options.locale);\n };\n}\n\nexport function getTranslate(context: Context): Translator {\n if (!context[TRANSLATE]) throw new Error(\"Translate plugin isn't loaded.\");\n return context[TRANSLATE];\n}\n\n// ----- Code ----- //\n\nfunction createTranslator(options: TranslatorOptions): Translator {\n const formatters = new Map<string, Formatter>();\n\n formatters.set(\"number\", (locale, value, options) => {\n return new Intl.NumberFormat(locale, options).format(Number(value));\n });\n formatters.set(\"datetime\", (locale, value, options) => {\n return new Intl.DateTimeFormat(locale, options).format(new Date(value));\n });\n formatters.set(\"list\", (locale, value, options) => {\n return new Intl.ListFormat(locale, options).format(value);\n });\n\n if (options.formatters) {\n for (const key in options.formatters) {\n formatters.set(key, options.formatters[key]);\n }\n }\n\n let lookup: LookupFn | undefined;\n\n const [currentLocale, setCurrentLocale] = createAtom(\"en\");\n const supportedLocales = [...Object.keys(options.translations)];\n\n /**\n * Loads translation for the locale.\n */\n async function setLocale(name?: string) {\n let locale!: string;\n\n if (name === undefined) {\n let names = [];\n\n if (typeof navigator !== \"undefined\") {\n const nav = navigator as any;\n\n if (nav.languages?.length > 0) {\n names.push(...nav.languages);\n } else if (nav.language) {\n names.push(nav.language);\n } else if (nav.browserLanguage) {\n names.push(nav.browserLanguage);\n } else if (nav.userLanguage) {\n names.push(nav.userLanguage);\n }\n }\n\n for (const name of names) {\n if (name in options.translations) {\n // Found a matching language.\n locale = name;\n break;\n }\n }\n } else {\n // Tag is the actual tag to set.\n if (name in options.translations) {\n locale = name;\n }\n }\n\n if (locale == null) {\n const firstLanguage = Object.keys(options.translations).at(0);\n if (firstLanguage) {\n locale = firstLanguage;\n }\n }\n\n if (!locale || !(locale in options.translations)) {\n throw new Error(`Locale '${name}' has no translation.`);\n }\n\n lookup = await createLookup(locale, formatters, options.translations[locale]);\n\n // Update locale string after init so t() signals will update.\n setCurrentLocale(locale);\n }\n\n function t(selector: string, options?: TOptions): Getter<string> {\n return compose(() => {\n currentLocale(); // track locale\n return lookup?.(selector, options) ?? selector;\n });\n }\n\n function format<\n K extends keyof BuiltInFormatters,\n V extends BuiltInFormatters[K][0],\n O extends BuiltInFormatters[K][1],\n >(name: K, value: Getter<V> | V, options?: O): Getter<string>;\n\n function format<V, O>(name: string, value: Getter<V> | V, options?: O): Getter<string>;\n\n function format(name: string, value: unknown, options?: Record<string, any>): Getter<string> {\n const callback = formatters.get(name);\n if (!callback) {\n throw new Error(`Unknown format: ${name}`);\n }\n\n return compose(() => callback(currentLocale(), unwrap(value), options ?? {}));\n }\n\n return {\n supportedLocales,\n currentLocale,\n setLocale,\n t,\n format,\n };\n}\n\n/**\n * Loads the translation and produces an efficient lookup function.\n */\nasync function createLookup(\n locale: string,\n formatters: Map<string, Formatter>,\n translation: TranslationFetchFn | LocalizedStrings,\n) {\n const strings = isFunction(translation) ? await translation() : translation;\n const entries = compile(strings);\n const templates = new Map(entries);\n\n /**\n * Looks up the template and produces the output. Any reactive values in `options` are tracked when used.\n */\n return function lookup(selector: string, options?: TOptions): string {\n if (options) {\n // Handle count (pluralization) and context. Keys become \"key_context_pluralization\".\n if (options.context != null) {\n selector += \"_\" + options.context;\n }\n if (options.count != null) {\n if (options.ordinal) {\n // Try to match the exact number key if there is one (e.g. \"myExampleKey_ordinal_(=2)\" when count is 2).\n const exact = `${selector}_ordinal_(=${options.count})`;\n if (templates.has(exact)) {\n selector = exact;\n } else {\n selector += \"_ordinal_\" + new Intl.PluralRules(locale, { type: \"ordinal\" }).select(unwrap(options.count));\n }\n } else {\n // Try to match the exact number key if there is one (e.g. \"myExampleKey_(=2)\" when count is 2).\n const exact = `${selector}_(=${options.count})`;\n if (templates.has(exact)) {\n selector = exact;\n } else {\n selector += \"_\" + new Intl.PluralRules(locale).select(unwrap(options.count));\n }\n }\n }\n }\n\n const template = templates.get(selector);\n if (!template) return selector;\n\n let output = \"\";\n\n for (let i = 0; i < template.length; i++) {\n output += template[i](options, formatters, locale);\n }\n\n return output;\n };\n}\n\n/**\n * Compiles an object of translated strings into a set of function templates.\n */\nexport function compile(strings: { [key: string]: any }, path: string[] = []): [string, CompiledTemplate][] {\n const entries: [string, CompiledTemplate][] = [];\n\n for (const key in strings) {\n switch (typeof strings[key]) {\n case \"string\":\n entries.push([[...path, key].join(\".\"), parseTemplate(strings[key])]);\n break;\n case \"object\":\n entries.push(...compile(strings[key], [...path, key]));\n break;\n default:\n throw new Error(\n `Expected to find a string or object at ${[...path, key].join(\".\")}. Got: ${typeof strings[key]}`,\n );\n }\n }\n\n return entries;\n}\n\nexport type TemplateSegmentFn = (\n options: Record<string, any> | undefined,\n formatters: Map<string, Formatter>,\n locale: string,\n) => string;\n\nexport type CompiledTemplate = TemplateSegmentFn[];\n\n/**\n * Parse a string template into an array of functions that will produce each piece of the output when called.\n */\nexport function parseTemplate(template: string): CompiledTemplate {\n const tokens = template.split(/(\\{\\{.*?\\}\\})/g);\n const segments: TemplateSegmentFn[] = [];\n\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (!token) continue;\n\n if (token.startsWith(\"{{\") && token.endsWith(\"}}\")) {\n const inner = token.slice(2, -2).trim();\n const parts = inner.split(\"|\").map((p) => p.trim());\n\n const name = parts[0];\n const parsedFormats: { name: string; options: Record<string, string> }[] = [];\n\n // Parse formatters at build-time to prevent string splitting on every render\n for (let j = 1; j < parts.length; j++) {\n const formatStr = parts[j];\n const match = formatStr.match(/^([a-zA-Z0-9_]+)(?:\\((.*)\\))?$/);\n\n if (match) {\n const formatName = match[1];\n const optionsStr = match[2];\n const optsObj: Record<string, string> = {};\n\n if (optionsStr) {\n const pairs = optionsStr.split(\",\");\n for (let k = 0; k < pairs.length; k++) {\n const pair = pairs[k];\n const colonIndex = pair.indexOf(\":\");\n if (colonIndex > -1) {\n optsObj[pair.slice(0, colonIndex).trim()] = pair.slice(colonIndex + 1).trim();\n }\n }\n }\n parsedFormats.push({ name: formatName, options: optsObj });\n } else {\n parsedFormats.push({ name: formatStr, options: {} });\n }\n }\n\n // Push the dynamic closure\n segments.push((options, formatters, locale) => {\n // Evaluate and track the specific option at runtime.\n // This code runs in the t() computed context.\n let value = options ? unwrap(options[name]) : undefined;\n\n for (let k = 0; k < parsedFormats.length; k++) {\n const fmt = parsedFormats[k];\n const formatterFn = formatters.get(fmt.name);\n if (formatterFn) {\n value = formatterFn(locale, value, fmt.options);\n }\n }\n\n return value != null ? String(value) : \"\";\n });\n } else {\n // Push a static closure that just returns the token\n segments.push(() => token);\n }\n }\n\n return segments;\n}\n"],"mappings":"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"}