@ryupold/vode 1.5.1 → 1.6.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.
package/dist/vode.mjs CHANGED
@@ -1,39 +1,32 @@
1
1
  // src/vode.ts
2
2
  var globals = {
3
- currentViewTransition: undefined,
4
- requestAnimationFrame: window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : (cb) => cb(),
5
- startViewTransition: document.startViewTransition ? document.startViewTransition.bind(document) : null
3
+ currentViewTransition: void 0,
4
+ requestAnimationFrame: !!window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : ((cb) => cb()),
5
+ startViewTransition: !!document.startViewTransition ? document.startViewTransition.bind(document) : null
6
6
  };
7
- function vode(tag, props, ...children) {
8
- if (!tag)
9
- throw new Error("first argument to vode() must be a tag name or a vode");
10
- if (Array.isArray(tag))
11
- return tag;
12
- else if (props)
13
- return [tag, props, ...children];
14
- else
15
- return [tag, ...children];
7
+ function vode(tag2, props2, ...children2) {
8
+ if (!tag2) throw new Error("first argument to vode() must be a tag name or a vode");
9
+ if (Array.isArray(tag2)) return tag2;
10
+ else if (props2) return [tag2, props2, ...children2];
11
+ else return [tag2, ...children2];
16
12
  }
17
13
  function app(container, state, dom, ...initialPatches) {
18
- if (!container?.parentElement)
19
- throw new Error("first argument to app() must be a valid HTMLElement inside the <html></html> document");
20
- if (!state || typeof state !== "object")
21
- throw new Error("second argument to app() must be a state object");
22
- if (typeof dom !== "function")
23
- throw new Error("third argument to app() must be a function that returns a vode");
14
+ if (!container?.parentElement) throw new Error("first argument to app() must be a valid HTMLElement inside the <html></html> document");
15
+ if (!state || typeof state !== "object") throw new Error("second argument to app() must be a state object");
16
+ if (typeof dom !== "function") throw new Error("third argument to app() must be a function that returns a vode");
24
17
  const _vode = {};
25
18
  _vode.syncRenderer = globals.requestAnimationFrame;
26
19
  _vode.asyncRenderer = globals.startViewTransition;
27
20
  _vode.qSync = null;
28
21
  _vode.qAsync = null;
29
22
  _vode.stats = { lastSyncRenderTime: 0, lastAsyncRenderTime: 0, syncRenderCount: 0, asyncRenderCount: 0, liveEffectCount: 0, patchCount: 0, syncRenderPatchCount: 0, asyncRenderPatchCount: 0 };
23
+ const patchableState = state;
30
24
  Object.defineProperty(state, "patch", {
31
25
  enumerable: false,
32
26
  configurable: true,
33
27
  writable: false,
34
28
  value: async (action, isAsync) => {
35
- if (!action || typeof action !== "function" && typeof action !== "object")
36
- return;
29
+ if (!action || typeof action !== "function" && typeof action !== "object") return;
37
30
  _vode.stats.patchCount++;
38
31
  if (action?.next) {
39
32
  const generator = action;
@@ -43,40 +36,41 @@ function app(container, state, dom, ...initialPatches) {
43
36
  while (v.done === false) {
44
37
  _vode.stats.liveEffectCount++;
45
38
  try {
46
- _vode.patch(v.value, isAsync);
39
+ patchableState.patch(v.value, isAsync);
47
40
  v = await generator.next();
48
41
  } finally {
49
42
  _vode.stats.liveEffectCount--;
50
43
  }
51
44
  }
52
- _vode.patch(v.value, isAsync);
45
+ patchableState.patch(v.value, isAsync);
53
46
  } finally {
54
47
  _vode.stats.liveEffectCount--;
55
48
  }
56
49
  } else if (action.then) {
57
50
  _vode.stats.liveEffectCount++;
58
51
  try {
59
- const nextState = await action;
60
- _vode.patch(nextState, isAsync);
52
+ const resolvedPatch = await action;
53
+ patchableState.patch(resolvedPatch, isAsync);
61
54
  } finally {
62
55
  _vode.stats.liveEffectCount--;
63
56
  }
64
57
  } else if (Array.isArray(action)) {
65
58
  if (action.length > 0) {
66
59
  for (const p of action) {
67
- _vode.patch(p, !document.hidden && !!_vode.asyncRenderer);
60
+ patchableState.patch(p, !document.hidden && !!_vode.asyncRenderer);
68
61
  }
69
62
  } else {
70
63
  _vode.qSync = mergeState(_vode.qSync || {}, _vode.qAsync, false);
71
64
  _vode.qAsync = null;
72
65
  try {
73
66
  globals.currentViewTransition?.skipTransition();
74
- } catch {}
67
+ } catch {
68
+ }
75
69
  _vode.stats.syncRenderPatchCount++;
76
70
  _vode.renderSync();
77
71
  }
78
72
  } else if (typeof action === "function") {
79
- _vode.patch(action(_vode.state), isAsync);
73
+ patchableState.patch(action(_vode.state), isAsync);
80
74
  } else {
81
75
  if (isAsync) {
82
76
  _vode.stats.asyncRenderPatchCount++;
@@ -93,7 +87,7 @@ function app(container, state, dom, ...initialPatches) {
93
87
  function renderDom(isAsync) {
94
88
  const sw = Date.now();
95
89
  const vom = dom(_vode.state);
96
- _vode.vode = render(_vode.state, _vode.patch, container.parentElement, 0, _vode.vode, vom);
90
+ _vode.vode = render(_vode.state, container.parentElement, 0, _vode.vode, vom);
97
91
  if (container.tagName.toUpperCase() !== vom[0].toUpperCase()) {
98
92
  container = _vode.vode.node;
99
93
  container._vode = _vode;
@@ -102,8 +96,7 @@ function app(container, state, dom, ...initialPatches) {
102
96
  _vode.stats.lastSyncRenderTime = Date.now() - sw;
103
97
  _vode.stats.syncRenderCount++;
104
98
  _vode.isRendering = false;
105
- if (_vode.qSync)
106
- _vode.renderSync();
99
+ if (_vode.qSync) _vode.renderSync();
107
100
  }
108
101
  }
109
102
  const sr = renderDom.bind(null, false);
@@ -113,8 +106,7 @@ function app(container, state, dom, ...initialPatches) {
113
106
  configurable: true,
114
107
  writable: false,
115
108
  value: () => {
116
- if (_vode.isRendering || !_vode.qSync)
117
- return;
109
+ if (_vode.isRendering || !_vode.qSync) return;
118
110
  _vode.isRendering = true;
119
111
  _vode.state = mergeState(_vode.state, _vode.qSync, true);
120
112
  _vode.qSync = null;
@@ -126,11 +118,9 @@ function app(container, state, dom, ...initialPatches) {
126
118
  configurable: true,
127
119
  writable: false,
128
120
  value: async () => {
129
- if (_vode.isAnimating || !_vode.qAsync)
130
- return;
121
+ if (_vode.isAnimating || !_vode.qAsync) return;
131
122
  await globals.currentViewTransition?.updateCallbackDone;
132
- if (_vode.isAnimating || !_vode.qAsync || document.hidden)
133
- return;
123
+ if (_vode.isAnimating || !_vode.qAsync || document.hidden) return;
134
124
  _vode.isAnimating = true;
135
125
  const sw = Date.now();
136
126
  try {
@@ -143,25 +133,28 @@ function app(container, state, dom, ...initialPatches) {
143
133
  _vode.stats.asyncRenderCount++;
144
134
  _vode.isAnimating = false;
145
135
  }
146
- if (_vode.qAsync)
147
- _vode.renderAsync();
136
+ if (_vode.qAsync) _vode.renderAsync();
148
137
  }
149
138
  });
150
- _vode.patch = state.patch;
151
- _vode.state = state;
139
+ _vode.state = patchableState;
152
140
  const root = container;
153
141
  root._vode = _vode;
154
- _vode.vode = render(state, _vode.patch, container.parentElement, Array.from(container.parentElement.children).indexOf(container), hydrate(container, true), dom(state));
142
+ _vode.vode = render(
143
+ state,
144
+ container.parentElement,
145
+ Array.from(container.parentElement.children).indexOf(container),
146
+ hydrate(container, true),
147
+ dom(state)
148
+ );
155
149
  for (const effect of initialPatches) {
156
- _vode.patch(effect);
150
+ patchableState.patch(effect);
157
151
  }
158
- return _vode.patch;
152
+ return (action) => patchableState.patch(action);
159
153
  }
160
154
  function defuse(container) {
161
155
  if (container?._vode) {
162
- let clearEvents = function(av) {
163
- if (!av?.node)
164
- return;
156
+ let clearEvents2 = function(av) {
157
+ if (!av?.node) return;
165
158
  const p = props(av);
166
159
  if (p) {
167
160
  for (const key in p) {
@@ -173,75 +166,72 @@ function defuse(container) {
173
166
  }
174
167
  const kids = children(av);
175
168
  if (kids) {
176
- for (let child of kids) {
177
- clearEvents(child);
169
+ for (let child2 of kids) {
170
+ clearEvents2(child2);
178
171
  }
179
172
  }
180
173
  };
174
+ var clearEvents = clearEvents2;
181
175
  const v = container._vode;
182
176
  delete container["_vode"];
183
- Object.defineProperty(v.state, "patch", { value: undefined });
184
- Object.defineProperty(v, "renderSync", { value: () => {} });
185
- Object.defineProperty(v, "renderAsync", { value: () => {} });
186
- clearEvents(v.vode);
177
+ Object.defineProperty(v.state, "patch", { value: void 0 });
178
+ Object.defineProperty(v, "renderSync", { value: () => {
179
+ } });
180
+ Object.defineProperty(v, "renderAsync", { value: () => {
181
+ } });
182
+ clearEvents2(v.vode);
187
183
  }
188
184
  }
189
185
  function hydrate(element, prepareForRender) {
190
186
  if (element?.nodeType === Node.TEXT_NODE) {
191
187
  if (element.nodeValue?.trim() !== "")
192
188
  return prepareForRender ? element : element.nodeValue;
193
- return;
189
+ return void 0;
194
190
  } else if (element.nodeType === Node.COMMENT_NODE) {
195
- return;
191
+ return void 0;
196
192
  } else if (element.nodeType === Node.ELEMENT_NODE) {
197
- const tag = element.tagName.toLowerCase();
198
- const root = [tag];
199
- if (prepareForRender)
200
- root.node = element;
193
+ const tag2 = element.tagName.toLowerCase();
194
+ const root = [tag2];
195
+ if (prepareForRender) root.node = element;
201
196
  if (element?.hasAttributes()) {
202
- const props = {};
197
+ const props2 = {};
203
198
  const attr = element.attributes;
204
199
  for (let a of attr) {
205
- props[a.name] = a.value;
200
+ props2[a.name] = a.value;
206
201
  }
207
- root.push(props);
202
+ root.push(props2);
208
203
  }
209
204
  if (element.hasChildNodes()) {
210
205
  const remove = [];
211
- for (let child of element.childNodes) {
212
- const wet = child && hydrate(child, prepareForRender);
213
- if (wet)
214
- root.push(wet);
215
- else if (child && prepareForRender)
216
- remove.push(child);
206
+ for (let child2 of element.childNodes) {
207
+ const wet = child2 && hydrate(child2, prepareForRender);
208
+ if (wet) root.push(wet);
209
+ else if (child2 && prepareForRender) remove.push(child2);
217
210
  }
218
- for (let child of remove) {
219
- child.remove();
211
+ for (let child2 of remove) {
212
+ child2.remove();
220
213
  }
221
214
  }
222
215
  return root;
223
216
  } else {
224
- return;
217
+ return void 0;
225
218
  }
226
219
  }
227
220
  function memo(compare, componentOrProps) {
228
- if (!compare || !Array.isArray(compare))
229
- throw new Error("first argument to memo() must be an array of values to compare");
230
- if (typeof componentOrProps !== "function")
231
- throw new Error("second argument to memo() must be a function that returns a vode or props object");
221
+ if (!compare || !Array.isArray(compare)) throw new Error("first argument to memo() must be an array of values to compare");
222
+ if (typeof componentOrProps !== "function") throw new Error("second argument to memo() must be a function that returns a vode or props object");
232
223
  componentOrProps.__memo = compare;
233
224
  return componentOrProps;
234
225
  }
235
226
  function createState(state) {
236
- if (!state || typeof state !== "object")
237
- throw new Error("createState() must be called with a state object");
227
+ if (!state || typeof state !== "object") throw new Error("createState() must be called with a state object");
238
228
  return state;
239
229
  }
240
230
  function createPatch(p) {
241
231
  return p;
242
232
  }
243
233
  function tag(v) {
244
- return v ? Array.isArray(v) ? v[0] : typeof v === "string" || v.nodeType === Node.TEXT_NODE ? "#text" : undefined : undefined;
234
+ return !!v ? Array.isArray(v) ? v[0] : typeof v === "string" || v.nodeType === Node.TEXT_NODE ? "#text" : void 0 : void 0;
245
235
  }
246
236
  function props(vode2) {
247
237
  if (Array.isArray(vode2) && vode2.length > 1 && vode2[1] && !Array.isArray(vode2[1])) {
@@ -249,7 +239,7 @@ function props(vode2) {
249
239
  return vode2[1];
250
240
  }
251
241
  }
252
- return;
242
+ return void 0;
253
243
  }
254
244
  function children(vode2) {
255
245
  const start = childrenStart(vode2);
@@ -260,23 +250,19 @@ function children(vode2) {
260
250
  }
261
251
  function childCount(vode2) {
262
252
  const start = childrenStart(vode2);
263
- if (start < 0)
264
- return 0;
253
+ if (start < 0) return 0;
265
254
  return vode2.length - start;
266
255
  }
267
256
  function child(vode2, index) {
268
257
  const start = childrenStart(vode2);
269
- if (start > 0)
270
- return vode2[index + start];
271
- else
272
- return;
258
+ if (start > 0) return vode2[index + start];
259
+ else return void 0;
273
260
  }
274
261
  function childrenStart(vode2) {
275
262
  return props(vode2) ? vode2.length > 2 ? 2 : -1 : Array.isArray(vode2) && vode2.length > 1 ? 1 : -1;
276
263
  }
277
264
  function mergeState(target, source, allowDeletion) {
278
- if (!source)
279
- return target;
265
+ if (!source) return target;
280
266
  for (const key in source) {
281
267
  const value = source[key];
282
268
  if (value && typeof value === "object") {
@@ -287,12 +273,9 @@ function mergeState(target, source, allowDeletion) {
287
273
  } else if (value instanceof Date && targetValue !== value) {
288
274
  target[key] = new Date(value);
289
275
  } else {
290
- if (Array.isArray(targetValue))
291
- target[key] = mergeState({}, value, allowDeletion);
292
- else if (typeof targetValue === "object")
293
- mergeState(target[key], value, allowDeletion);
294
- else
295
- target[key] = mergeState({}, value, allowDeletion);
276
+ if (Array.isArray(targetValue)) target[key] = mergeState({}, value, allowDeletion);
277
+ else if (typeof targetValue === "object") mergeState(target[key], value, allowDeletion);
278
+ else target[key] = mergeState({}, value, allowDeletion);
296
279
  }
297
280
  } else if (Array.isArray(value)) {
298
281
  target[key] = [...value];
@@ -301,7 +284,7 @@ function mergeState(target, source, allowDeletion) {
301
284
  } else {
302
285
  target[key] = mergeState({}, value, allowDeletion);
303
286
  }
304
- } else if (value === undefined && allowDeletion) {
287
+ } else if (value === void 0 && allowDeletion) {
305
288
  delete target[key];
306
289
  } else {
307
290
  target[key] = value;
@@ -309,7 +292,7 @@ function mergeState(target, source, allowDeletion) {
309
292
  }
310
293
  return target;
311
294
  }
312
- function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
295
+ function render(state, parent, childIndex, oldVode, newVode, xmlns) {
313
296
  try {
314
297
  newVode = remember(state, newVode, oldVode);
315
298
  const isNoVode = !newVode || typeof newVode === "number" || typeof newVode === "boolean";
@@ -319,9 +302,9 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
319
302
  const oldIsText = oldVode?.nodeType === Node.TEXT_NODE;
320
303
  const oldNode = oldIsText ? oldVode : oldVode?.node;
321
304
  if (isNoVode) {
322
- oldNode?.onUnmount && patch(oldNode.onUnmount(oldNode));
305
+ oldNode?.onUnmount && state.patch(oldNode.onUnmount(oldNode));
323
306
  oldNode?.remove();
324
- return;
307
+ return void 0;
325
308
  }
326
309
  const isText = !isNoVode && isTextVode(newVode);
327
310
  const isNode = !isNoVode && isNaturalVode(newVode);
@@ -342,7 +325,7 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
342
325
  if (isText && (!oldNode || !oldIsText)) {
343
326
  const text = document.createTextNode(newVode);
344
327
  if (oldNode) {
345
- oldNode.onUnmount && patch(oldNode.onUnmount(oldNode));
328
+ oldNode.onUnmount && state.patch(oldNode.onUnmount(oldNode));
346
329
  oldNode.replaceWith(text);
347
330
  } else {
348
331
  if (parent.childNodes[childIndex]) {
@@ -356,15 +339,19 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
356
339
  if (isNode && (!oldNode || oldIsText || oldVode[0] !== newVode[0])) {
357
340
  const newvode = newVode;
358
341
  if (1 in newvode) {
359
- newvode[1] = remember(state, newvode[1], undefined);
342
+ newvode[1] = remember(state, newvode[1], void 0);
360
343
  }
361
344
  const properties = props(newVode);
362
345
  xmlns = properties?.xmlns || xmlns;
363
346
  const newNode = xmlns ? document.createElementNS(xmlns, newVode[0]) : document.createElement(newVode[0]);
364
347
  newVode.node = newNode;
365
- patchProperties(state, patch, newNode, undefined, properties);
348
+ patchProperties(state, newNode, void 0, properties);
349
+ if (!!properties && "catch" in properties) {
350
+ newVode.node["catch"] = null;
351
+ newVode.node.removeAttribute("catch");
352
+ }
366
353
  if (oldNode) {
367
- oldNode.onUnmount && patch(oldNode.onUnmount(oldNode));
354
+ oldNode.onUnmount && state.patch(oldNode.onUnmount(oldNode));
368
355
  oldNode.replaceWith(newNode);
369
356
  } else {
370
357
  if (parent.childNodes[childIndex]) {
@@ -375,44 +362,42 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
375
362
  }
376
363
  const newChildren = children(newVode);
377
364
  if (newChildren) {
378
- for (let i = 0;i < newChildren.length; i++) {
365
+ for (let i = 0; i < newChildren.length; i++) {
379
366
  const child2 = newChildren[i];
380
- const attached = render(state, patch, newNode, i, undefined, child2, xmlns);
367
+ const attached = render(state, newNode, i, void 0, child2, xmlns);
381
368
  newVode[properties ? i + 2 : i + 1] = attached;
382
369
  }
383
370
  }
384
- newNode.onMount && patch(newNode.onMount(newNode));
371
+ newNode.onMount && state.patch(newNode.onMount(newNode));
385
372
  return newVode;
386
373
  }
387
374
  if (!oldIsText && isNode && oldVode[0] === newVode[0]) {
388
375
  newVode.node = oldNode;
389
376
  const newvode = newVode;
390
377
  const oldvode = oldVode;
391
- let hasProps = false;
378
+ const properties = props(newVode);
379
+ let hasProps = !!properties;
380
+ const oldProps = props(oldVode);
392
381
  if (newvode[1]?.__memo) {
393
382
  const prev = newvode[1];
394
383
  newvode[1] = remember(state, newvode[1], oldvode[1]);
395
384
  if (prev !== newvode[1]) {
396
- const properties = props(newVode);
397
- patchProperties(state, patch, oldNode, props(oldVode), properties);
398
- hasProps = !!properties;
385
+ patchProperties(state, oldNode, oldProps, properties);
399
386
  }
400
387
  } else {
401
- const properties = props(newVode);
402
- patchProperties(state, patch, oldNode, props(oldVode), properties);
403
- hasProps = !!properties;
404
- if (hasProps && "catch" in properties) {
405
- newVode.node["catch"] = null;
406
- newVode.node.removeAttribute("catch");
407
- }
388
+ patchProperties(state, oldNode, oldProps, properties);
389
+ }
390
+ if (!!properties?.catch && oldProps?.catch !== properties.catch) {
391
+ newVode.node["catch"] = null;
392
+ newVode.node.removeAttribute("catch");
408
393
  }
409
394
  const newKids = children(newVode);
410
395
  const oldKids = children(oldVode);
411
396
  if (newKids) {
412
- for (let i = 0;i < newKids.length; i++) {
397
+ for (let i = 0; i < newKids.length; i++) {
413
398
  const child2 = newKids[i];
414
399
  const oldChild = oldKids && oldKids[i];
415
- const attached = render(state, patch, oldNode, i, oldChild, child2, xmlns);
400
+ const attached = render(state, oldNode, i, oldChild, child2, xmlns);
416
401
  if (attached) {
417
402
  newVode[hasProps ? i + 2 : i + 1] = attached;
418
403
  }
@@ -420,8 +405,8 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
420
405
  }
421
406
  if (oldKids) {
422
407
  const newKidsCount = newKids ? newKids.length : 0;
423
- for (let i = oldKids.length - 1;i >= newKidsCount; i--) {
424
- render(state, patch, oldNode, i, oldKids[i], undefined, xmlns);
408
+ for (let i = oldKids.length - 1; i >= newKidsCount; i--) {
409
+ render(state, oldNode, i, oldKids[i], void 0, xmlns);
425
410
  }
426
411
  }
427
412
  return newVode;
@@ -430,12 +415,19 @@ function render(state, patch, parent, childIndex, oldVode, newVode, xmlns) {
430
415
  const catchVode = props(newVode)?.catch;
431
416
  if (catchVode) {
432
417
  const handledVode = typeof catchVode === "function" ? catchVode(state, error) : catchVode;
433
- return render(state, patch, parent, childIndex, hydrate(newVode?.node || oldVode?.node, true), handledVode, xmlns);
418
+ return render(
419
+ state,
420
+ parent,
421
+ childIndex,
422
+ hydrate(newVode?.node || oldVode?.node, true),
423
+ handledVode,
424
+ xmlns
425
+ );
434
426
  } else {
435
427
  throw error;
436
428
  }
437
429
  }
438
- return;
430
+ return void 0;
439
431
  }
440
432
  function isNaturalVode(x) {
441
433
  return Array.isArray(x) && x.length > 0 && typeof x[0] === "string";
@@ -450,14 +442,13 @@ function remember(state, present, past) {
450
442
  const pastMemo = past?.__memo;
451
443
  if (Array.isArray(presentMemo) && Array.isArray(pastMemo) && presentMemo.length === pastMemo.length) {
452
444
  let same = true;
453
- for (let i = 0;i < presentMemo.length; i++) {
445
+ for (let i = 0; i < presentMemo.length; i++) {
454
446
  if (presentMemo[i] !== pastMemo[i]) {
455
447
  same = false;
456
448
  break;
457
449
  }
458
450
  }
459
- if (same)
460
- return past;
451
+ if (same) return past;
461
452
  }
462
453
  const newRender = unwrap(present, state);
463
454
  if (typeof newRender === "object") {
@@ -472,18 +463,15 @@ function unwrap(c, s) {
472
463
  return c;
473
464
  }
474
465
  }
475
- function patchProperties(s, patch, node, oldProps, newProps) {
476
- if (!newProps && !oldProps)
477
- return;
466
+ function patchProperties(s, node, oldProps, newProps) {
467
+ if (!newProps && !oldProps) return;
478
468
  if (oldProps) {
479
469
  for (const key in oldProps) {
480
470
  const oldValue = oldProps[key];
481
471
  const newValue = newProps?.[key];
482
472
  if (oldValue !== newValue) {
483
- if (newProps)
484
- newProps[key] = patchProperty(s, patch, node, key, oldValue, newValue);
485
- else
486
- patchProperty(s, patch, node, key, oldValue, undefined);
473
+ if (newProps) newProps[key] = patchProperty(s, node, key, oldValue, newValue);
474
+ else patchProperty(s, node, key, oldValue, void 0);
487
475
  }
488
476
  }
489
477
  }
@@ -491,23 +479,22 @@ function patchProperties(s, patch, node, oldProps, newProps) {
491
479
  for (const key in newProps) {
492
480
  if (!(key in oldProps)) {
493
481
  const newValue = newProps[key];
494
- newProps[key] = patchProperty(s, patch, node, key, undefined, newValue);
482
+ newProps[key] = patchProperty(s, node, key, void 0, newValue);
495
483
  }
496
484
  }
497
485
  } else if (newProps) {
498
486
  for (const key in newProps) {
499
487
  const newValue = newProps[key];
500
- newProps[key] = patchProperty(s, patch, node, key, undefined, newValue);
488
+ newProps[key] = patchProperty(s, node, key, void 0, newValue);
501
489
  }
502
490
  }
503
491
  }
504
- function patchProperty(s, patch, node, key, oldValue, newValue) {
492
+ function patchProperty(s, node, key, oldValue, newValue) {
505
493
  if (key === "style") {
506
494
  if (!newValue) {
507
495
  node.style.cssText = "";
508
496
  } else if (typeof newValue === "string") {
509
- if (oldValue !== newValue)
510
- node.style.cssText = newValue;
497
+ if (oldValue !== newValue) node.style.cssText = newValue;
511
498
  } else if (oldValue && typeof oldValue === "object") {
512
499
  for (let k in oldValue) {
513
500
  const nv = newValue[k];
@@ -538,9 +525,9 @@ function patchProperty(s, patch, node, key, oldValue, newValue) {
538
525
  let eventHandler = null;
539
526
  if (typeof newValue === "function") {
540
527
  const action = newValue;
541
- eventHandler = (evt) => patch(action(s, evt));
528
+ eventHandler = (evt) => s.patch(action(s, evt));
542
529
  } else if (typeof newValue === "object") {
543
- eventHandler = () => patch(newValue);
530
+ eventHandler = () => s.patch(newValue);
544
531
  }
545
532
  node[key] = eventHandler;
546
533
  } else {
@@ -548,7 +535,7 @@ function patchProperty(s, patch, node, key, oldValue, newValue) {
548
535
  }
549
536
  } else {
550
537
  node[key] = newValue;
551
- if (newValue === undefined || newValue === null || newValue === false)
538
+ if (newValue === void 0 || newValue === null || newValue === false)
552
539
  node.removeAttribute(key);
553
540
  else
554
541
  node.setAttribute(key, newValue);
@@ -565,6 +552,7 @@ function classString(classProp) {
565
552
  else
566
553
  return "";
567
554
  }
555
+
568
556
  // src/vode-tags.ts
569
557
  var A = "a";
570
558
  var ABBR = "abbr";
@@ -767,14 +755,13 @@ var MTR = "mtr";
767
755
  var MUNDER = "munder";
768
756
  var MUNDEROVER = "munderover";
769
757
  var SEMANTICS = "semantics";
758
+
770
759
  // src/merge-class.ts
771
760
  function mergeClass(...classes) {
772
- if (!classes || classes.length === 0)
773
- return null;
774
- if (classes.length === 1)
775
- return classes[0];
761
+ if (!classes || classes.length === 0) return null;
762
+ if (classes.length === 1) return classes[0];
776
763
  let finalClass = classes[0];
777
- for (let index = 1;index < classes.length; index++) {
764
+ for (let index = 1; index < classes.length; index++) {
778
765
  const a = finalClass, b = classes[index];
779
766
  if (!a) {
780
767
  finalClass = b;
@@ -783,16 +770,16 @@ function mergeClass(...classes) {
783
770
  } else if (typeof a === "string" && typeof b === "string") {
784
771
  const aSplit = a.split(" ");
785
772
  const bSplit = b.split(" ");
786
- const classSet = new Set([...aSplit, ...bSplit]);
773
+ const classSet = /* @__PURE__ */ new Set([...aSplit, ...bSplit]);
787
774
  finalClass = Array.from(classSet).join(" ").trim();
788
775
  } else if (typeof a === "string" && Array.isArray(b)) {
789
- const classSet = new Set([...b, ...a.split(" ")]);
776
+ const classSet = /* @__PURE__ */ new Set([...b, ...a.split(" ")]);
790
777
  finalClass = Array.from(classSet).join(" ").trim();
791
778
  } else if (Array.isArray(a) && typeof b === "string") {
792
- const classSet = new Set([...a, ...b.split(" ")]);
779
+ const classSet = /* @__PURE__ */ new Set([...a, ...b.split(" ")]);
793
780
  finalClass = Array.from(classSet).join(" ").trim();
794
781
  } else if (Array.isArray(a) && Array.isArray(b)) {
795
- const classSet = new Set([...a, ...b]);
782
+ const classSet = /* @__PURE__ */ new Set([...a, ...b]);
796
783
  finalClass = Array.from(classSet).join(" ").trim();
797
784
  } else if (typeof a === "string" && typeof b === "object") {
798
785
  finalClass = { [a]: true, ...b };
@@ -815,25 +802,43 @@ function mergeClass(...classes) {
815
802
  aa[bKey] = b[bKey];
816
803
  }
817
804
  finalClass = aa;
818
- } else
819
- throw new Error(`cannot merge classes of ${a} (${typeof a}) and ${b} (${typeof b})`);
805
+ } else throw new Error(`cannot merge classes of ${a} (${typeof a}) and ${b} (${typeof b})`);
820
806
  }
821
807
  return finalClass;
822
808
  }
809
+
810
+ // src/merge-style.ts
811
+ var tempDivForStyling = document.createElement("div");
812
+ function mergeStyle(...props2) {
813
+ try {
814
+ const merged = tempDivForStyling.style;
815
+ for (const style of props2) {
816
+ if (typeof style === "object" && style !== null) {
817
+ for (const key in style) {
818
+ merged[key] = style[key];
819
+ }
820
+ } else if (typeof style === "string") {
821
+ merged.cssText += ";" + style;
822
+ }
823
+ }
824
+ return merged.cssText;
825
+ } finally {
826
+ tempDivForStyling.style.cssText = "";
827
+ }
828
+ }
829
+
823
830
  // src/state-context.ts
824
- class KeyStateContext {
825
- state;
826
- path;
827
- keys;
831
+ var KeyStateContext = class {
828
832
  constructor(state, path) {
829
833
  this.state = state;
830
834
  this.path = path;
831
835
  this.keys = path.split(".");
832
836
  }
837
+ keys;
833
838
  get() {
834
839
  const keys = this.keys;
835
- let raw = this.state ? this.state[keys[0]] : undefined;
836
- for (let i = 1;i < keys.length && !!raw; i++) {
840
+ let raw = this.state ? this.state[keys[0]] : void 0;
841
+ for (let i = 1; i < keys.length && !!raw; i++) {
837
842
  raw = raw[keys[i]];
838
843
  }
839
844
  return raw;
@@ -852,6 +857,19 @@ class KeyStateContext {
852
857
  this.state.patch(this.createPatch(value));
853
858
  }
854
859
  }
860
+ /**
861
+ * Creates a render-patch for the parent state by setting a nested sub-state value while creating necessary structure.
862
+ *
863
+ * @example
864
+ * ```typescript
865
+ * const ctx = new KeyStateContext(state, 'user.profile.settings');
866
+ * const patch = ctx.createPatch({ theme: 'light' });
867
+ * // patch is { user: { profile: { settings: { theme: 'light' } } } }
868
+ * ```
869
+ *
870
+ * @param value
871
+ * @returns {{key-path}:{...: value}} render-patch for the parent state
872
+ */
855
873
  createPatch(value) {
856
874
  const renderPatch = {};
857
875
  this.putDeep(value, renderPatch);
@@ -865,7 +883,7 @@ class KeyStateContext {
865
883
  if (typeof raw !== "object" || raw === null) {
866
884
  target[keys[i]] = raw = {};
867
885
  }
868
- for (i = 1;i < keys.length - 1; i++) {
886
+ for (i = 1; i < keys.length - 1; i++) {
869
887
  const p = raw;
870
888
  raw = raw[keys[i]];
871
889
  if (typeof raw !== "object" || raw === null) {
@@ -880,237 +898,233 @@ class KeyStateContext {
880
898
  target[keys[0]] = value;
881
899
  }
882
900
  }
883
- }
884
-
885
- class DelegateStateContext {
886
- state;
887
- get;
888
- put;
889
- patch;
901
+ };
902
+ var DelegateStateContext = class {
890
903
  constructor(state, get, put, patch) {
891
904
  this.state = state;
892
905
  this.get = get;
893
906
  this.put = put;
894
907
  this.patch = patch;
895
908
  }
896
- }
909
+ };
897
910
  export {
898
- vode,
899
- tag,
900
- props,
901
- mergeClass,
902
- memo,
903
- hydrate,
904
- globals,
905
- defuse,
906
- createState,
907
- createPatch,
908
- childrenStart,
909
- children,
910
- childCount,
911
- child,
912
- app,
913
- WBR,
914
- VIEW,
915
- VIDEO,
916
- VAR,
917
- USE,
918
- UL,
919
- U,
920
- TSPAN,
921
- TRACK,
922
- TR,
923
- TITLE,
924
- TIME,
925
- THEAD,
926
- TH,
927
- TFOOT,
928
- TEXTPATH,
929
- TEXTAREA,
930
- TEXT,
931
- TEMPLATE,
932
- TD,
933
- TBODY,
934
- TABLE,
935
- SYMBOL,
936
- SWITCH,
937
- SVG,
938
- SUP,
939
- SUMMARY,
940
- SUB,
941
- STYLE,
942
- STRONG,
943
- STOP,
944
- SPAN,
945
- SOURCE,
946
- SMALL,
947
- SLOT,
948
- SET,
949
- SEMANTICS,
950
- SELECT,
951
- SECTION,
952
- SEARCH,
953
- SCRIPT,
954
- SAMP,
955
- S,
956
- RUBY,
957
- RT,
958
- RP,
959
- RECT,
960
- RADIALGRADIENT,
961
- Q,
962
- PROGRESS,
963
- PRE,
964
- POLYLINE,
965
- POLYGON,
966
- PICTURE,
967
- PATTERN,
968
- PATH,
969
- P,
970
- OUTPUT,
971
- OPTION,
972
- OPTGROUP,
973
- OL,
974
- OBJECT,
975
- NOSCRIPT,
976
- NAV,
977
- MUNDEROVER,
978
- MUNDER,
979
- MTR,
980
- MTEXT,
981
- MTD,
982
- MTABLE,
983
- MSUP,
984
- MSUBSUP,
985
- MSUB,
986
- MSTYLE,
987
- MSQRT,
988
- MSPACE,
989
- MS,
990
- MROW,
991
- MROOT,
992
- MPRESCRIPTS,
993
- MPHANTOM,
994
- MPATH,
995
- MPADDED,
996
- MOVER,
997
- MO,
998
- MN,
999
- MMULTISCRIPTS,
1000
- MI,
1001
- MFRAC,
1002
- METER,
1003
- METADATA,
1004
- META,
1005
- MERROR,
1006
- MENU,
1007
- MATH,
1008
- MASK,
1009
- MARKER,
1010
- MARK,
1011
- MAP,
1012
- MAIN,
1013
- MACTION,
1014
- LINK,
1015
- LINEARGRADIENT,
1016
- LINE,
1017
- LI,
1018
- LEGEND,
1019
- LABEL,
1020
- KeyStateContext,
1021
- KBD,
1022
- INS,
1023
- INPUT,
1024
- IMG,
1025
- IMAGE,
1026
- IFRAME,
1027
- I,
1028
- HTML,
1029
- HR,
1030
- HGROUP,
1031
- HEADER,
1032
- HEAD,
1033
- H6,
1034
- H5,
1035
- H4,
1036
- H3,
1037
- H2,
1038
- H1,
1039
- G,
1040
- FORM,
1041
- FOREIGNOBJECT,
1042
- FOOTER,
1043
- FILTER,
1044
- FIGURE,
1045
- FIGCAPTION,
1046
- FIELDSET,
1047
- FETURBULENCE,
1048
- FETILE,
1049
- FESPOTLIGHT,
1050
- FESPECULARLIGHTING,
1051
- FEPOINTLIGHT,
1052
- FEOFFSET,
1053
- FEMORPHOLOGY,
1054
- FEMERGENODE,
1055
- FEMERGE,
1056
- FEIMAGE,
1057
- FEGAUSSIANBLUR,
1058
- FEFUNCR,
1059
- FEFUNCG,
1060
- FEFUNCB,
1061
- FEFUNCA,
1062
- FEFLOOD,
1063
- FEDROPSHADOW,
1064
- FEDISTANTLIGHT,
1065
- FEDISPLACEMENTMAP,
1066
- FEDIFFUSELIGHTING,
1067
- FECONVOLVEMATRIX,
1068
- FECOMPOSITE,
1069
- FECOMPONENTTRANSFER,
1070
- FECOLORMATRIX,
1071
- FEBLEND,
1072
- EMBED,
1073
- EM,
1074
- ELLIPSE,
1075
- DelegateStateContext,
1076
- DT,
1077
- DL,
1078
- DIV,
1079
- DIALOG,
1080
- DFN,
1081
- DETAILS,
1082
- DESC,
1083
- DEL,
1084
- DEFS,
1085
- DD,
1086
- DATALIST,
1087
- DATA,
1088
- COLGROUP,
1089
- COL,
1090
- CODE,
1091
- CLIPPATH,
1092
- CITE,
1093
- CIRCLE,
1094
- CAPTION,
1095
- CANVAS,
1096
- BUTTON,
1097
- BR,
1098
- BODY,
1099
- BLOCKQUOTE,
1100
- BDO,
1101
- BDI,
1102
- BASE,
1103
- B,
1104
- AUDIO,
1105
- ASIDE,
1106
- ARTICLE,
1107
- AREA,
1108
- ANNOTATION_XML,
1109
- ANNOTATION,
1110
- ANIMATETRANSFORM,
1111
- ANIMATEMOTION,
1112
- ANIMATE,
1113
- ADDRESS,
911
+ A,
1114
912
  ABBR,
1115
- A
913
+ ADDRESS,
914
+ ANIMATE,
915
+ ANIMATEMOTION,
916
+ ANIMATETRANSFORM,
917
+ ANNOTATION,
918
+ ANNOTATION_XML,
919
+ AREA,
920
+ ARTICLE,
921
+ ASIDE,
922
+ AUDIO,
923
+ B,
924
+ BASE,
925
+ BDI,
926
+ BDO,
927
+ BLOCKQUOTE,
928
+ BODY,
929
+ BR,
930
+ BUTTON,
931
+ CANVAS,
932
+ CAPTION,
933
+ CIRCLE,
934
+ CITE,
935
+ CLIPPATH,
936
+ CODE,
937
+ COL,
938
+ COLGROUP,
939
+ DATA,
940
+ DATALIST,
941
+ DD,
942
+ DEFS,
943
+ DEL,
944
+ DESC,
945
+ DETAILS,
946
+ DFN,
947
+ DIALOG,
948
+ DIV,
949
+ DL,
950
+ DT,
951
+ DelegateStateContext,
952
+ ELLIPSE,
953
+ EM,
954
+ EMBED,
955
+ FEBLEND,
956
+ FECOLORMATRIX,
957
+ FECOMPONENTTRANSFER,
958
+ FECOMPOSITE,
959
+ FECONVOLVEMATRIX,
960
+ FEDIFFUSELIGHTING,
961
+ FEDISPLACEMENTMAP,
962
+ FEDISTANTLIGHT,
963
+ FEDROPSHADOW,
964
+ FEFLOOD,
965
+ FEFUNCA,
966
+ FEFUNCB,
967
+ FEFUNCG,
968
+ FEFUNCR,
969
+ FEGAUSSIANBLUR,
970
+ FEIMAGE,
971
+ FEMERGE,
972
+ FEMERGENODE,
973
+ FEMORPHOLOGY,
974
+ FEOFFSET,
975
+ FEPOINTLIGHT,
976
+ FESPECULARLIGHTING,
977
+ FESPOTLIGHT,
978
+ FETILE,
979
+ FETURBULENCE,
980
+ FIELDSET,
981
+ FIGCAPTION,
982
+ FIGURE,
983
+ FILTER,
984
+ FOOTER,
985
+ FOREIGNOBJECT,
986
+ FORM,
987
+ G,
988
+ H1,
989
+ H2,
990
+ H3,
991
+ H4,
992
+ H5,
993
+ H6,
994
+ HEAD,
995
+ HEADER,
996
+ HGROUP,
997
+ HR,
998
+ HTML,
999
+ I,
1000
+ IFRAME,
1001
+ IMAGE,
1002
+ IMG,
1003
+ INPUT,
1004
+ INS,
1005
+ KBD,
1006
+ KeyStateContext,
1007
+ LABEL,
1008
+ LEGEND,
1009
+ LI,
1010
+ LINE,
1011
+ LINEARGRADIENT,
1012
+ LINK,
1013
+ MACTION,
1014
+ MAIN,
1015
+ MAP,
1016
+ MARK,
1017
+ MARKER,
1018
+ MASK,
1019
+ MATH,
1020
+ MENU,
1021
+ MERROR,
1022
+ META,
1023
+ METADATA,
1024
+ METER,
1025
+ MFRAC,
1026
+ MI,
1027
+ MMULTISCRIPTS,
1028
+ MN,
1029
+ MO,
1030
+ MOVER,
1031
+ MPADDED,
1032
+ MPATH,
1033
+ MPHANTOM,
1034
+ MPRESCRIPTS,
1035
+ MROOT,
1036
+ MROW,
1037
+ MS,
1038
+ MSPACE,
1039
+ MSQRT,
1040
+ MSTYLE,
1041
+ MSUB,
1042
+ MSUBSUP,
1043
+ MSUP,
1044
+ MTABLE,
1045
+ MTD,
1046
+ MTEXT,
1047
+ MTR,
1048
+ MUNDER,
1049
+ MUNDEROVER,
1050
+ NAV,
1051
+ NOSCRIPT,
1052
+ OBJECT,
1053
+ OL,
1054
+ OPTGROUP,
1055
+ OPTION,
1056
+ OUTPUT,
1057
+ P,
1058
+ PATH,
1059
+ PATTERN,
1060
+ PICTURE,
1061
+ POLYGON,
1062
+ POLYLINE,
1063
+ PRE,
1064
+ PROGRESS,
1065
+ Q,
1066
+ RADIALGRADIENT,
1067
+ RECT,
1068
+ RP,
1069
+ RT,
1070
+ RUBY,
1071
+ S,
1072
+ SAMP,
1073
+ SCRIPT,
1074
+ SEARCH,
1075
+ SECTION,
1076
+ SELECT,
1077
+ SEMANTICS,
1078
+ SET,
1079
+ SLOT,
1080
+ SMALL,
1081
+ SOURCE,
1082
+ SPAN,
1083
+ STOP,
1084
+ STRONG,
1085
+ STYLE,
1086
+ SUB,
1087
+ SUMMARY,
1088
+ SUP,
1089
+ SVG,
1090
+ SWITCH,
1091
+ SYMBOL,
1092
+ TABLE,
1093
+ TBODY,
1094
+ TD,
1095
+ TEMPLATE,
1096
+ TEXT,
1097
+ TEXTAREA,
1098
+ TEXTPATH,
1099
+ TFOOT,
1100
+ TH,
1101
+ THEAD,
1102
+ TIME,
1103
+ TITLE,
1104
+ TR,
1105
+ TRACK,
1106
+ TSPAN,
1107
+ U,
1108
+ UL,
1109
+ USE,
1110
+ VAR,
1111
+ VIDEO,
1112
+ VIEW,
1113
+ WBR,
1114
+ app,
1115
+ child,
1116
+ childCount,
1117
+ children,
1118
+ childrenStart,
1119
+ createPatch,
1120
+ createState,
1121
+ defuse,
1122
+ globals,
1123
+ hydrate,
1124
+ memo,
1125
+ mergeClass,
1126
+ mergeStyle,
1127
+ props,
1128
+ tag,
1129
+ vode
1116
1130
  };