@vmz/core 0.3.10 → 0.3.11

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.
@@ -142,6 +142,7 @@ export type DirectApi = {
142
142
  adoptEnter: (node: Element) => boolean;
143
143
  adoptLeave: () => void;
144
144
  projectDefaultSlot: (hostEl: HTMLElement, node: Node) => void;
145
+ projectNamedSlot: (hostEl: HTMLElement, name: string, node: Node) => void;
145
146
  setHtml: (el: Element, value: unknown) => void;
146
147
  setShow: (el: HTMLElement, condition: unknown) => void;
147
148
  bindHtml: (inst: DirectInstance, bindingId: BindingId, deps: string[], get: PatchFn, el: Element) => void;
@@ -3,6 +3,14 @@ export declare function settlePendingChildMounts(inst: any): Promise<void>;
3
3
  export declare function runDirectCreate(Component: any, inst: any): any;
4
4
  export declare function findOwnedDefaultSlot(root: any): any;
5
5
  export declare function findOwnedDefaultSlotTarget(root: any): any;
6
+ /**
7
+ * Owned `<slot name="…">` outlet for a named projection.
8
+ *
9
+ * Same ownership rule as {@link findOwnedDefaultSlot}: a nested component host
10
+ * (`[data-vmz]` / `__vmzInst`) is a boundary, so projecting `header` into a Card
11
+ * can never capture a Button's own named slot.
12
+ */
13
+ export declare function findOwnedNamedSlot(root: any, name: any): any;
6
14
  export declare function createInstance(Component: any, props?: any): any;
7
15
  export declare function destroy(inst: any): void;
8
16
  /**
@@ -13,15 +21,19 @@ export declare function destroy(inst: any): void;
13
21
  export declare function slotAnchorFor(node: any): any;
14
22
  export declare function insertProjectedSlotNode(target: any, node: any): any;
15
23
  /**
16
- * Hold projected children until the component's default slot exists.
24
+ * Hold projected children until the component slot exists.
17
25
  *
18
26
  * A slot inside an unmounted `v-if` branch (closed drawer/dialog, loading
19
27
  * skeleton) is absent at projection time. Appending to the component root would
20
28
  * paint the child into the live page, so keep it detached and splice it in when
21
29
  * the slot is mounted.
30
+ *
31
+ * `name` parks for a specific `slot name="…"` outlet. Named projections never
32
+ * fall back into the default slot: a missing named outlet keeps the node parked
33
+ * (or drops it on hosts without MutationObserver) instead of polluting it.
22
34
  */
23
- export declare function parkSlotNode(hostEl: any, node: any): void;
24
- /** Move parked children into the now-mounted default slot. Returns true when drained. */
35
+ export declare function parkSlotNode(hostEl: any, node: any, name?: any): void;
36
+ /** Move parked children into the now-mounted slot. Returns true when any drained. */
25
37
  export declare function flushParkedSlotNodes(hostEl: any): boolean;
26
38
  export declare function disposeDomTree(root: any): void;
27
39
  export declare function snapshotInstanceState(inst: any): {};
@@ -120,6 +120,37 @@ export function findOwnedDefaultSlotTarget(root) {
120
120
  };
121
121
  return walk(root);
122
122
  }
123
+ /**
124
+ * Owned `<slot name="…">` outlet for a named projection.
125
+ *
126
+ * Same ownership rule as {@link findOwnedDefaultSlot}: a nested component host
127
+ * (`[data-vmz]` / `__vmzInst`) is a boundary, so projecting `header` into a Card
128
+ * can never capture a Button's own named slot.
129
+ */
130
+ export function findOwnedNamedSlot(root, name) {
131
+ if (!root || root.nodeType !== 1)
132
+ return null;
133
+ if (name == null || name === '')
134
+ return null;
135
+ const wanted = String(name);
136
+ const tag = String(root.tagName || '').toLowerCase();
137
+ if (tag === 'slot' && root.getAttribute('name') === wanted)
138
+ return root;
139
+ const kids = root.children;
140
+ if (!kids || !kids.length)
141
+ return null;
142
+ for (let i = 0; i < kids.length; i++) {
143
+ const c = kids[i];
144
+ if (c.nodeType !== 1)
145
+ continue;
146
+ if (c.hasAttribute('data-vmz') || c.__vmzInst)
147
+ continue;
148
+ const hit = findOwnedNamedSlot(c, wanted);
149
+ if (hit)
150
+ return hit;
151
+ }
152
+ return null;
153
+ }
123
154
  export function createInstance(Component, props = {}) {
124
155
  if (precision.enabled)
125
156
  precision.componentExecs++;
@@ -203,17 +234,24 @@ export function insertProjectedSlotNode(target, node) {
203
234
  return anchor;
204
235
  }
205
236
  /**
206
- * Hold projected children until the component's default slot exists.
237
+ * Hold projected children until the component slot exists.
207
238
  *
208
239
  * A slot inside an unmounted `v-if` branch (closed drawer/dialog, loading
209
240
  * skeleton) is absent at projection time. Appending to the component root would
210
241
  * paint the child into the live page, so keep it detached and splice it in when
211
242
  * the slot is mounted.
243
+ *
244
+ * `name` parks for a specific `slot name="…"` outlet. Named projections never
245
+ * fall back into the default slot: a missing named outlet keeps the node parked
246
+ * (or drops it on hosts without MutationObserver) instead of polluting it.
212
247
  */
213
- export function parkSlotNode(hostEl, node) {
248
+ export function parkSlotNode(hostEl, node, name = null) {
214
249
  if (!hostEl || !node)
215
250
  return;
251
+ const slotName = name == null ? null : String(name);
216
252
  if (typeof MutationObserver === 'undefined') {
253
+ if (slotName != null)
254
+ return;
217
255
  // Non-browser DOM (unit hosts): preserve the legacy root fallback.
218
256
  const child = hostEl.__vmzInst;
219
257
  const root = (child && child.__vmzDomRoot) || hostEl;
@@ -223,8 +261,28 @@ export function parkSlotNode(hostEl, node) {
223
261
  hostEl.appendChild(node);
224
262
  return;
225
263
  }
226
- const parked = hostEl.__vmzSlotParked || (hostEl.__vmzSlotParked = []);
227
- parked.push(node);
264
+ if (slotName == null) {
265
+ const parked = hostEl.__vmzSlotParked || (hostEl.__vmzSlotParked = []);
266
+ parked.push(node);
267
+ }
268
+ else {
269
+ namedSlotParked(hostEl, slotName).push(node);
270
+ }
271
+ ensureSlotObserver(hostEl);
272
+ }
273
+ function namedSlotParked(hostEl, name) {
274
+ const map = hostEl.__vmzNamedSlotParked || (hostEl.__vmzNamedSlotParked = new Map());
275
+ const list = map.get(name);
276
+ if (list)
277
+ return list;
278
+ const fresh = [];
279
+ map.set(name, fresh);
280
+ return fresh;
281
+ }
282
+ function namedSlotAnchor(hostEl) {
283
+ return hostEl.__vmzNamedSlotAnchor || (hostEl.__vmzNamedSlotAnchor = new Map());
284
+ }
285
+ function ensureSlotObserver(hostEl) {
228
286
  if (hostEl.__vmzSlotObserver)
229
287
  return;
230
288
  hostEl.__vmzSlotObserver = new MutationObserver(() => {
@@ -235,44 +293,64 @@ export function parkSlotNode(hostEl, node) {
235
293
  hostEl.__vmzSlotObserver.observe(scope, { childList: true, subtree: true });
236
294
  }
237
295
  }
238
- /** Move parked children into the now-mounted default slot. Returns true when drained. */
296
+ /** Move parked children into the now-mounted slot. Returns true when any drained. */
239
297
  export function flushParkedSlotNodes(hostEl) {
240
298
  if (!hostEl)
241
299
  return false;
242
- const parked = hostEl.__vmzSlotParked;
243
- if (!parked || !parked.length)
244
- return false;
245
300
  const child = hostEl.__vmzInst;
246
301
  const root = (child && child.__vmzDomRoot) || hostEl;
247
302
  if (!root || root.nodeType !== 1)
248
303
  return false;
249
- const target = findOwnedDefaultSlotTarget(root);
250
- if (!target || !target.parentNode)
251
- return false;
252
- if (hostEl.__vmzSlotObserver) {
304
+ let drained = false;
305
+ const parkedDefault = hostEl.__vmzSlotParked;
306
+ if (parkedDefault && parkedDefault.length) {
307
+ const target = findOwnedDefaultSlotTarget(root);
308
+ if (target && target.parentNode) {
309
+ hostEl.__vmzSlotParked = [];
310
+ hostEl.__vmzSlotAnchor = insertParked(hostEl, target, parkedDefault);
311
+ drained = true;
312
+ }
313
+ }
314
+ const named = hostEl.__vmzNamedSlotParked;
315
+ if (named && named.size) {
316
+ for (const [name, nodes] of named) {
317
+ if (!nodes.length) {
318
+ named.delete(name);
319
+ continue;
320
+ }
321
+ const target = findOwnedNamedSlot(root, name);
322
+ if (!target || !target.parentNode)
323
+ continue;
324
+ named.delete(name);
325
+ namedSlotAnchor(hostEl).set(name, insertParked(hostEl, target, nodes));
326
+ drained = true;
327
+ }
328
+ }
329
+ const stillParked = (hostEl.__vmzSlotParked && hostEl.__vmzSlotParked.length > 0) ||
330
+ (hostEl.__vmzNamedSlotParked && hostEl.__vmzNamedSlotParked.size > 0);
331
+ if (drained && !stillParked && hostEl.__vmzSlotObserver) {
253
332
  hostEl.__vmzSlotObserver.disconnect();
254
333
  hostEl.__vmzSlotObserver = null;
255
334
  }
256
- hostEl.__vmzSlotParked = [];
335
+ return drained;
336
+ }
337
+ function insertParked(hostEl, target, parked) {
257
338
  const anchor = slotAnchorFor(parked[parked.length - 1]);
258
339
  const tag = String(target.tagName || '').toLowerCase();
259
340
  if (tag === 'slot') {
260
341
  const frag = typeof document !== 'undefined' ? document.createDocumentFragment() : null;
261
342
  if (!frag) {
262
343
  target.replaceWith(parked[0]);
263
- hostEl.__vmzSlotAnchor = anchor;
264
- return true;
344
+ return anchor;
265
345
  }
266
346
  for (const node of parked)
267
347
  frag.appendChild(node);
268
348
  target.replaceWith(frag);
269
- hostEl.__vmzSlotAnchor = anchor;
270
- return true;
349
+ return anchor;
271
350
  }
272
351
  for (const node of parked)
273
352
  target.appendChild(node);
274
- hostEl.__vmzSlotAnchor = anchor;
275
- return true;
353
+ return anchor;
276
354
  }
277
355
  export function disposeDomTree(root) {
278
356
  if (!root)
@@ -304,6 +382,10 @@ export function disposeDomTree(root) {
304
382
  node.__vmzSlotParked = [];
305
383
  if (node.__vmzSlotAnchor)
306
384
  node.__vmzSlotAnchor = null;
385
+ if (node.__vmzNamedSlotParked)
386
+ node.__vmzNamedSlotParked = null;
387
+ if (node.__vmzNamedSlotAnchor)
388
+ node.__vmzNamedSlotAnchor = null;
307
389
  let child = node.firstChild;
308
390
  while (child) {
309
391
  const next = child.nextSibling;
@@ -83,4 +83,13 @@ export declare const directApi: {
83
83
  * Uses {@link findOwnedDefaultSlot} so nested Button/Link slots are not stolen.
84
84
  */
85
85
  projectDefaultSlot(hostEl: any, node: any): void;
86
+ /**
87
+ * Project parent children into a nested Direct component's `<slot name="…">`.
88
+ *
89
+ * Named projections are name-only (scope-slot values are not passed yet). The
90
+ * outlet search stops at nested component hosts, so a `header` projection never
91
+ * steals a nested Button's own named slot. A name with no outlet parks under that
92
+ * name — it must not fall through into the default slot.
93
+ */
94
+ projectNamedSlot(hostEl: any, name: any, node: any): void;
86
95
  };
@@ -2,7 +2,7 @@ import { mergeClassParts, mergeStyleParts } from '../../shared/dom-attr-normaliz
2
2
  import { applyDirectHostBox } from '../direct-host-box.js';
3
3
  import { createUnknownComponentElement } from '../unknown-component.js';
4
4
  import { applyDomAttr, eventPropHandlerName } from './attributes.js';
5
- import { createInstance, disposeDomTree, findOwnedDefaultSlotTarget, insertProjectedSlotNode, parkSlotNode, runDirectCreate, slotAnchorFor, stripFns, } from './component.js';
5
+ import { createInstance, disposeDomTree, findOwnedDefaultSlotTarget, findOwnedNamedSlot, insertProjectedSlotNode, parkSlotNode, runDirectCreate, slotAnchorFor, stripFns, } from './component.js';
6
6
  import { isEventEntryStrategy, noteDomCreate, noteDomRemove, scheduleClientOn } from './lifecycle.js';
7
7
  import { components, resolveComponent } from './registry.js';
8
8
  import { beginEventFlush, endEventFlush, inferHandlerMethod, methodAllowsSyncEventFlush, registerBind, runDomEventHandler, runPatch, scheduleRefresh, unregisterBind, } from '../reactivity/patch-scheduler.js';
@@ -524,4 +524,41 @@ export const directApi = {
524
524
  // the component root, where it would otherwise leak into the rendered page.
525
525
  parkSlotNode(hostEl, node);
526
526
  },
527
+ /**
528
+ * Project parent children into a nested Direct component's `<slot name="…">`.
529
+ *
530
+ * Named projections are name-only (scope-slot values are not passed yet). The
531
+ * outlet search stops at nested component hosts, so a `header` projection never
532
+ * steals a nested Button's own named slot. A name with no outlet parks under that
533
+ * name — it must not fall through into the default slot.
534
+ */
535
+ projectNamedSlot(hostEl, name, node) {
536
+ if (!hostEl || node == null)
537
+ return;
538
+ const key = name == null ? '' : String(name);
539
+ if (!key || key === 'default') {
540
+ directApi.projectDefaultSlot(hostEl, node);
541
+ return;
542
+ }
543
+ const child = hostEl.__vmzInst;
544
+ let root = (child && child.__vmzDomRoot) || hostEl;
545
+ if (!root || root.nodeType !== 1)
546
+ root = hostEl;
547
+ const target = root && root.nodeType === 1 ? findOwnedNamedSlot(root, key) : null;
548
+ if (target && target.parentNode) {
549
+ const anchors = hostEl.__vmzNamedSlotAnchor || (hostEl.__vmzNamedSlotAnchor = new Map());
550
+ anchors.set(key, insertProjectedSlotNode(target, node));
551
+ return;
552
+ }
553
+ // The named `<slot>` was replaced by an earlier projected child: append after
554
+ // the last one for the same name instead of re-searching.
555
+ const anchors = hostEl.__vmzNamedSlotAnchor;
556
+ const anchor = anchors && anchors.get(key);
557
+ if (anchor && anchor.parentNode) {
558
+ anchors.set(key, slotAnchorFor(node));
559
+ anchor.parentNode.insertBefore(node, anchor.nextSibling);
560
+ return;
561
+ }
562
+ parkSlotNode(hostEl, node, key);
563
+ },
527
564
  };
@@ -16,6 +16,7 @@ export { settlePendingChildMounts } from './dom/component.js';
16
16
  export { runDirectCreate } from './dom/component.js';
17
17
  export { findOwnedDefaultSlot } from './dom/component.js';
18
18
  export { findOwnedDefaultSlotTarget } from './dom/component.js';
19
+ export { findOwnedNamedSlot } from './dom/component.js';
19
20
  export { createInstance } from './dom/component.js';
20
21
  export { destroy } from './dom/component.js';
21
22
  export { disposeDomTree } from './dom/component.js';
@@ -16,6 +16,7 @@ export { settlePendingChildMounts } from './dom/component.js';
16
16
  export { runDirectCreate } from './dom/component.js';
17
17
  export { findOwnedDefaultSlot } from './dom/component.js';
18
18
  export { findOwnedDefaultSlotTarget } from './dom/component.js';
19
+ export { findOwnedNamedSlot } from './dom/component.js';
19
20
  export { createInstance } from './dom/component.js';
20
21
  export { destroy } from './dom/component.js';
21
22
  export { disposeDomTree } from './dom/component.js';
@@ -307,6 +307,64 @@ function makeVirtualEl(tag) {
307
307
  });
308
308
  return node;
309
309
  }
310
+ /**
311
+ * Owned `<slot>` outlet in a serialize el tree.
312
+ *
313
+ * `name === null` matches the default outlet (no `name` attr). Named lookups require
314
+ * an exact match and stop at nested component shells (`data-vmz`), mirroring the
315
+ * browser runtime ownership boundary.
316
+ */
317
+ function findOwnedSerializeSlot(n, name) {
318
+ if (!n || typeof n !== 'object')
319
+ return null;
320
+ if (n.__kind === 'frag') {
321
+ for (const c of n.children || []) {
322
+ const hit = findOwnedSerializeSlot(c, name);
323
+ if (hit)
324
+ return hit;
325
+ }
326
+ return null;
327
+ }
328
+ if (n.__kind !== 'el')
329
+ return null;
330
+ if (n.tag === 'slot') {
331
+ const outletName = n.attrs && n.attrs.name != null ? String(n.attrs.name) : '';
332
+ if (name == null ? !outletName : outletName === name)
333
+ return n;
334
+ }
335
+ for (const c of n.children || []) {
336
+ if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
337
+ continue;
338
+ const hit = findOwnedSerializeSlot(c, name);
339
+ if (hit)
340
+ return hit;
341
+ }
342
+ return null;
343
+ }
344
+ function findOwnedSerializeSlotTarget(n, name) {
345
+ const slot = findOwnedSerializeSlot(n, name);
346
+ if (slot)
347
+ return slot;
348
+ if (name != null)
349
+ return null;
350
+ if (!n || n.__kind !== 'el')
351
+ return null;
352
+ const tag = String(n.tag || '').toLowerCase();
353
+ if ((tag === 'button' || tag === 'a') && n.attrs && n.attrs['data-vmz-ui'] === 'button')
354
+ return n;
355
+ if (n.attrs && n.attrs['data-vmz'] != null)
356
+ return null;
357
+ for (const c of n.children || []) {
358
+ if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
359
+ continue;
360
+ const hit = findOwnedSerializeSlotTarget(c, name);
361
+ if (hit)
362
+ return hit;
363
+ }
364
+ return null;
365
+ }
366
+ /** Outlets that already received projected content (fallback children dropped once). */
367
+ const filledSerializeSlots = new WeakSet();
310
368
  const serializeApi = {
311
369
  _inst: null,
312
370
  _branchBinds: null,
@@ -476,69 +534,25 @@ const serializeApi = {
476
534
  return;
477
535
  // serializeApi.component returns a serialize el tree (or island shell).
478
536
  const root = hostEl.__kind === 'el' ? hostEl : null;
479
- const findOwnedSlot = (n) => {
480
- if (!n || typeof n !== 'object')
481
- return null;
482
- if (n.__kind === 'frag') {
483
- for (const c of n.children || []) {
484
- const hit = findOwnedSlot(c);
485
- if (hit)
486
- return hit;
487
- }
488
- return null;
489
- }
490
- if (n.__kind !== 'el')
491
- return null;
492
- if (n.tag === 'slot' && !(n.attrs && n.attrs.name))
493
- return n;
494
- for (const c of n.children || []) {
495
- if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
496
- continue;
497
- const hit = findOwnedSlot(c);
498
- if (hit)
499
- return hit;
500
- }
501
- return null;
502
- };
503
- const findOwnedSlotTarget = (n) => {
504
- const slot = findOwnedSlot(n);
505
- if (slot)
506
- return slot;
507
- if (!n || n.__kind !== 'el')
508
- return null;
509
- const tag = String(n.tag || '').toLowerCase();
510
- if ((tag === 'button' || tag === 'a') && n.attrs && n.attrs['data-vmz-ui'] === 'button')
511
- return n;
512
- if (n.attrs && n.attrs['data-vmz'] != null)
513
- return null;
514
- for (const c of n.children || []) {
515
- if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
516
- continue;
517
- const hit = findOwnedSlotTarget(c);
518
- if (hit)
519
- return hit;
520
- }
521
- return null;
522
- };
523
537
  // Prefer searching the component body (first child of host wrapper).
524
538
  let target = null;
525
539
  if (root) {
526
540
  for (const c of root.children || []) {
527
541
  if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
528
542
  continue;
529
- target = findOwnedSlotTarget(c);
543
+ target = findOwnedSerializeSlotTarget(c, null);
530
544
  if (target)
531
545
  break;
532
546
  }
533
547
  if (!target)
534
- target = findOwnedSlotTarget(root);
548
+ target = findOwnedSerializeSlotTarget(root, null);
535
549
  }
536
550
  if (target) {
537
551
  if (target.tag === 'slot') {
538
552
  target.__rawHtml = null;
539
553
  if (!Array.isArray(target.children))
540
554
  target.children = [];
541
- // Append ??multiple projectDefaultSlot calls must accumulate (SSR).
555
+ // Append — multiple projectDefaultSlot calls must accumulate (SSR).
542
556
  // Client path replaces the live <slot> then appends siblings; serialize must push.
543
557
  target.children.push(node);
544
558
  return;
@@ -552,6 +566,46 @@ const serializeApi = {
552
566
  // mounted (closed overlay, loading skeleton). Mirror the browser runtime and
553
567
  // drop them instead of painting them into the component root.
554
568
  },
569
+ /**
570
+ * Project parent children into a nested component's `<slot name="…">` outlet.
571
+ *
572
+ * Named projections are name-only (scope-slot values are not passed yet). Only an
573
+ * outlet with the exact `name` accepts the node — a missing name drops it instead
574
+ * of landing in the default slot. Fallback children stop rendering once the outlet
575
+ * has projected content.
576
+ */
577
+ projectNamedSlot(hostEl, name, node) {
578
+ if (!hostEl || node == null)
579
+ return;
580
+ const key = name == null ? '' : String(name);
581
+ if (!key || key === 'default') {
582
+ serializeApi.projectDefaultSlot(hostEl, node);
583
+ return;
584
+ }
585
+ const root = hostEl.__kind === 'el' ? hostEl : null;
586
+ let target = null;
587
+ if (root) {
588
+ for (const c of root.children || []) {
589
+ if (c && c.__kind === 'el' && c.attrs && c.attrs['data-vmz'] != null)
590
+ continue;
591
+ target = findOwnedSerializeSlotTarget(c, key);
592
+ if (target)
593
+ break;
594
+ }
595
+ if (!target)
596
+ target = findOwnedSerializeSlotTarget(root, key);
597
+ }
598
+ if (!target)
599
+ return;
600
+ target.__rawHtml = null;
601
+ if (!Array.isArray(target.children))
602
+ target.children = [];
603
+ if (!filledSerializeSlots.has(target)) {
604
+ filledSerializeSlots.add(target);
605
+ target.children.length = 0;
606
+ }
607
+ target.children.push(node);
608
+ },
555
609
  setHtml(el, value) {
556
610
  if (!el || el.__kind !== 'el')
557
611
  return;
package/package.json CHANGED
@@ -68,12 +68,12 @@
68
68
  "main": "./dist/faces/server.js",
69
69
  "name": "@vmz/core",
70
70
  "optionalDependencies": {
71
- "@vmz/vmz-darwin-arm64": "0.3.10",
72
- "@vmz/vmz-darwin-x64": "0.3.10",
73
- "@vmz/vmz-linux-arm64": "0.3.10",
74
- "@vmz/vmz-linux-x64": "0.3.10",
75
- "@vmz/vmz-win32-arm64": "0.3.10",
76
- "@vmz/vmz-win32-x64": "0.3.10"
71
+ "@vmz/vmz-darwin-arm64": "0.3.11",
72
+ "@vmz/vmz-darwin-x64": "0.3.11",
73
+ "@vmz/vmz-linux-arm64": "0.3.11",
74
+ "@vmz/vmz-linux-x64": "0.3.11",
75
+ "@vmz/vmz-win32-arm64": "0.3.11",
76
+ "@vmz/vmz-win32-x64": "0.3.11"
77
77
  },
78
78
  "publishConfig": {
79
79
  "access": "public"
@@ -88,5 +88,5 @@
88
88
  },
89
89
  "type": "module",
90
90
  "types": "./dist/faces/index.d.ts",
91
- "version": "0.3.10"
91
+ "version": "0.3.11"
92
92
  }