@solidjs/web 2.0.0-beta.15 → 2.0.0-beta.17

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/web.js CHANGED
@@ -59,9 +59,9 @@ const syncOptions = {
59
59
  sync: true
60
60
  };
61
61
  const effect = (fn, effectFn, options) => createRenderEffect(fn, effectFn, options ? {
62
- transparent: true,
63
62
  sync: true,
64
- ...options
63
+ ...options,
64
+ transparent: !options.scope
65
65
  } : transparentOptions);
66
66
  const memo = fn => createMemo(() => fn(), syncOptions);
67
67
 
@@ -329,20 +329,41 @@ function addEvent(node, name, handler, delegate) {
329
329
  }
330
330
  function style(node, value, prev) {
331
331
  if (!value) {
332
- if (prev) setAttribute(node, "style");
332
+ if (prev || node._$styles) {
333
+ setAttribute(node, "style");
334
+ node._$styles = undefined;
335
+ }
333
336
  return;
334
337
  }
335
338
  const nodeStyle = node.style;
336
- if (typeof value === "string") return nodeStyle.cssText = value;
337
- typeof prev === "string" && (nodeStyle.cssText = prev = undefined);
338
- prev || (prev = {});
339
+ if (typeof value === "string") {
340
+ node._$styles = undefined;
341
+ return nodeStyle.cssText = value;
342
+ }
343
+ if (typeof prev === "string") {
344
+ nodeStyle.cssText = "";
345
+ prev = undefined;
346
+ }
347
+ let applied = node._$styles;
348
+ if (!applied) {
349
+ applied = node._$styles = prev ? {
350
+ ...prev
351
+ } : {};
352
+ }
339
353
  let v, s;
354
+ for (s in applied) {
355
+ if (value[s] == null) {
356
+ nodeStyle.removeProperty(s);
357
+ delete applied[s];
358
+ }
359
+ }
340
360
  for (s in value) {
341
361
  v = value[s];
342
- if (v !== prev[s]) nodeStyle.setProperty(s, v);
343
- delete prev[s];
362
+ if (v != null && v !== applied[s]) {
363
+ nodeStyle.setProperty(s, v);
364
+ applied[s] = v;
365
+ }
344
366
  }
345
- for (s in prev) value[s] == null && nodeStyle.removeProperty(s);
346
367
  }
347
368
  function setStyleProperty(node, name, value) {
348
369
  value != null ? node.style.setProperty(name, value) : node.style.removeProperty(name);
@@ -381,19 +402,28 @@ function ref(fn, element) {
381
402
  const resolved = untrack(fn);
382
403
  runWithOwner(null, () => applyRef(resolved, element));
383
404
  }
405
+ function scope(fn) {
406
+ fn.$s = true;
407
+ return fn;
408
+ }
409
+ const SCOPE_OPTIONS = {
410
+ scope: true
411
+ };
412
+ function stripTextSeparators(nodes) {
413
+ let j = 0;
414
+ for (let i = 0; i < nodes.length; i++) {
415
+ if (nodes[i].nodeType === 8 && nodes[i].nodeValue === "!$") nodes[i].remove();else nodes[j++] = nodes[i];
416
+ }
417
+ nodes.length = j;
418
+ return nodes;
419
+ }
384
420
  function insert(parent, accessor, marker, initial, options) {
385
421
  const multi = marker !== undefined;
386
422
  const host = options && options.host;
387
423
  if (multi && !initial) initial = [];
388
424
  if (isHydrating(parent)) {
389
425
  if (!multi && initial === undefined && parent) initial = [...parent.childNodes];
390
- if (Array.isArray(initial)) {
391
- let j = 0;
392
- for (let i = 0; i < initial.length; i++) {
393
- if (initial[i].nodeType === 8 && initial[i].nodeValue === "!$") initial[i].remove();else initial[j++] = initial[i];
394
- }
395
- initial.length = j;
396
- }
426
+ if (Array.isArray(initial)) stripTextSeparators(initial);
397
427
  }
398
428
  if (typeof accessor !== "function") {
399
429
  accessor = normalize(accessor, initial, multi, true);
@@ -409,10 +439,34 @@ function insert(parent, accessor, marker, initial, options) {
409
439
  initial = [placeholder];
410
440
  }
411
441
  let current = initial;
442
+ function reclaimSwappedRegion() {
443
+ if (!sharedConfig.hydrating || !current || !parent.isConnected) return;
444
+ const first = Array.isArray(current) ? current[0] : current;
445
+ if (!first || !first.nodeType || first.isConnected) return;
446
+ let nodes;
447
+ if (marker) {
448
+ nodes = [];
449
+ let node = marker.previousSibling,
450
+ depth = 0;
451
+ while (node) {
452
+ if (node.nodeType === 8) {
453
+ const v = node.nodeValue;
454
+ if (v === "/") depth++;else if (v === "$") {
455
+ if (depth === 0) break;
456
+ depth--;
457
+ }
458
+ }
459
+ nodes.unshift(node);
460
+ node = node.previousSibling;
461
+ }
462
+ } else nodes = [...parent.childNodes];
463
+ current = stripTextSeparators(nodes);
464
+ }
412
465
  effect(prev => {
466
+ reclaimSwappedRegion();
413
467
  const value = normalize(accessor(), current, multi, true);
414
468
  if (typeof value !== "function") return value;
415
- effect(() => normalize(value, current, multi), inner => {
469
+ effect(() => (reclaimSwappedRegion(), normalize(value, current, multi)), inner => {
416
470
  insertExpression(parent, inner, current, marker);
417
471
  current = inner;
418
472
  host && tagHost(current, host);
@@ -426,7 +480,11 @@ function insert(parent, accessor, marker, initial, options) {
426
480
  insertExpression(parent, value, current, marker);
427
481
  current = value;
428
482
  host && tagHost(current, host);
429
- }, options);
483
+ },
484
+ accessor.$s ? options ? {
485
+ ...options,
486
+ scope: true
487
+ } : SCOPE_OPTIONS : options);
430
488
  }
431
489
  function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
432
490
  const nodeName = node.nodeName;
@@ -445,19 +503,117 @@ function assign(node, props, skipChildren, prevProps = {}, skipRef = false) {
445
503
  prevProps[prop] = assignProp(node, prop, props[prop], prevProps[prop], skipRef, nodeName);
446
504
  }
447
505
  }
506
+ const ASSET_REMOVAL_GRACE = 100;
507
+ const assetRegistry = new Map();
508
+ function assetEntryKey(descriptor) {
509
+ if (descriptor.policy === "exclusive") return "x|" + descriptor.key;
510
+ return descriptor.type === "inline-style" ? "i|" + descriptor.id : descriptor.type + "|" + descriptor.href;
511
+ }
512
+ function findAssetElement(selector, attr, value) {
513
+ const nodes = document.querySelectorAll(selector);
514
+ for (let i = 0; i < nodes.length; i++) {
515
+ if (nodes[i].getAttribute(attr) === value) return nodes[i];
516
+ }
517
+ return null;
518
+ }
519
+ function mountAssetElement(descriptor) {
520
+ let el;
521
+ if (descriptor.type === "inline-style") {
522
+ el = findAssetElement("style[data-asset]", "data-asset", descriptor.id);
523
+ if (!el) {
524
+ el = document.createElement("style");
525
+ el.setAttribute("data-asset", descriptor.id);
526
+ el.textContent = descriptor.content || "";
527
+ }
528
+ } else {
529
+ const rel = descriptor.type === "module" ? "modulepreload" : "stylesheet";
530
+ el = findAssetElement(`link[rel="${rel}"]`, "href", descriptor.href);
531
+ if (!el) {
532
+ el = document.createElement("link");
533
+ el.rel = rel;
534
+ el.href = descriptor.href;
535
+ }
536
+ }
537
+ if (descriptor.attrs) {
538
+ for (const name in descriptor.attrs) el.setAttribute(name, descriptor.attrs[name]);
539
+ }
540
+ if (!el.isConnected) document.head.appendChild(el);
541
+ return el;
542
+ }
543
+ function acquireAsset(descriptor) {
544
+ const key = assetEntryKey(descriptor);
545
+ let entry = assetRegistry.get(key);
546
+ if (descriptor.policy === "exclusive") {
547
+ if (!entry) {
548
+ entry = {
549
+ original: descriptor.get(),
550
+ set: descriptor.set,
551
+ writers: []
552
+ };
553
+ assetRegistry.set(key, entry);
554
+ }
555
+ const writer = {
556
+ value: descriptor.value
557
+ };
558
+ entry.writers.push(writer);
559
+ entry.set(writer.value);
560
+ let released = false;
561
+ return () => {
562
+ if (released) return;
563
+ released = true;
564
+ const index = entry.writers.indexOf(writer);
565
+ const wasTop = index === entry.writers.length - 1;
566
+ entry.writers.splice(index, 1);
567
+ if (!wasTop) return;
568
+ if (entry.writers.length) {
569
+ entry.set(entry.writers[entry.writers.length - 1].value);
570
+ } else {
571
+ entry.set(entry.original);
572
+ assetRegistry.delete(key);
573
+ }
574
+ };
575
+ }
576
+ if (!entry) {
577
+ entry = {
578
+ count: 0,
579
+ element: null,
580
+ timer: null
581
+ };
582
+ assetRegistry.set(key, entry);
583
+ }
584
+ if (entry.timer) {
585
+ clearTimeout(entry.timer);
586
+ entry.timer = null;
587
+ }
588
+ entry.count++;
589
+ if (!entry.element || !entry.element.isConnected) entry.element = mountAssetElement(descriptor);
590
+ let released = false;
591
+ return () => {
592
+ if (released) return;
593
+ released = true;
594
+ if (--entry.count > 0) return;
595
+ entry.timer = setTimeout(() => {
596
+ assetRegistry.delete(key);
597
+ entry.element && entry.element.remove();
598
+ }, ASSET_REMOVAL_GRACE);
599
+ };
600
+ }
448
601
  function loadModuleAssets(mapping) {
449
602
  const hy = globalThis._$HY;
450
603
  if (!hy) return;
451
604
  const pending = [];
452
- for (const moduleUrl in mapping) {
453
- if (hy.modules[moduleUrl]) continue;
454
- const entryUrl = mapping[moduleUrl];
455
- if (!hy.loading[moduleUrl]) {
456
- hy.loading[moduleUrl] = import(entryUrl).then(mod => {
457
- hy.modules[moduleUrl] = mod;
605
+ for (const key in mapping) {
606
+ if (hy.modules[key]) continue;
607
+ const entryUrl = mapping[key];
608
+ if (!hy.loading[key]) {
609
+ hy.loading[key] = import(entryUrl).then(mod => {
610
+ hy.modules[key] = mod;
611
+ }, err => {
612
+ delete hy.loading[key];
613
+ throw err;
458
614
  });
459
615
  }
460
- pending.push(hy.loading[moduleUrl]);
616
+ pending.push(hy.loading[key]);
461
617
  }
462
618
  return pending.length ? Promise.all(pending).then(() => {}) : undefined;
463
619
  }
@@ -502,8 +658,11 @@ function hydrate$1(code, element, options = {}) {
502
658
  } finally {
503
659
  sharedConfig.hydrating = false;
504
660
  }
505
- }, () => {
661
+ }, err => {
662
+ console.error("Hydration module preload failed, falling back to client render:", err);
506
663
  sharedConfig.hydrating = false;
664
+ sharedConfig.registry = undefined;
665
+ disposer = render$1(code, element, [...element.childNodes], options);
507
666
  });
508
667
  return () => disposer && disposer();
509
668
  }
@@ -573,17 +732,32 @@ function runHydrationEvents() {
573
732
  const [el, e] = events[0];
574
733
  if (!completed.has(el)) return;
575
734
  events.shift();
576
- let match;
735
+ let matchContainer, matchState, matchDistance, matches;
577
736
  for (const [container, state] of delegatedContainers) {
578
737
  if (!state.handlers.has(e.type)) continue;
579
738
  const entry = findOwner(e.target, state);
580
- if (entry && (!match || entry.distance < match.distance)) match = {
581
- container,
582
- state,
583
- distance: entry.distance
584
- };
739
+ if (!entry) continue;
740
+ if (matchContainer) {
741
+ if (!matches) matches = [{
742
+ container: matchContainer,
743
+ state: matchState,
744
+ distance: matchDistance
745
+ }];
746
+ matches.push({
747
+ container,
748
+ state,
749
+ distance: entry.distance
750
+ });
751
+ } else {
752
+ matchContainer = container;
753
+ matchState = state;
754
+ matchDistance = entry.distance;
755
+ }
585
756
  }
586
- if (match) eventHandler(e, match.container, match.state);
757
+ if (matches) {
758
+ matches.sort((a, b) => a.distance - b.distance);
759
+ for (let i = 0; i < matches.length; i++) eventHandler(e, matches[i].container, matches[i].state);
760
+ } else if (matchContainer) eventHandler(e, matchContainer, matchState);
587
761
  }
588
762
  if (sharedConfig.done) {
589
763
  sharedConfig.events = _$HY.events = null;
@@ -654,11 +828,16 @@ function eventHandler(e, container, state) {
654
828
  if (sharedConfig.registry && sharedConfig.events) {
655
829
  if (sharedConfig.events.find(([el, ev]) => ev === e)) return;
656
830
  }
657
- if (e[$$EVENT_OWNER]) return;
831
+ const prev = e[$$EVENT_OWNER];
832
+ let resumeNode;
833
+ if (prev) {
834
+ if (prev === true || prev === container || !container.contains(prev)) return;
835
+ resumeNode = prev;
836
+ }
658
837
  const owner = state && (state.owners.size === 1 && state.owners.has(container) ? container : findOwner(e.target, state)?.owner);
659
838
  if (state && !owner) return;
660
839
  e[$$EVENT_OWNER] = owner || true;
661
- let node = e.target;
840
+ let node = resumeNode || e.target;
662
841
  const key = `$$${e.type}`;
663
842
  const oriTarget = e.target;
664
843
  const boundary = owner || container || e.currentTarget;
@@ -688,7 +867,10 @@ function eventHandler(e, container, state) {
688
867
  return node || boundary || document;
689
868
  }
690
869
  });
691
- if (e.composedPath) {
870
+ if (resumeNode) {
871
+ if (resumeNode === e.target) node = resumeNode._$host || resumeNode.parentNode || resumeNode.host;
872
+ if (node && node !== boundary) walkUpTree();
873
+ } else if (e.composedPath) {
692
874
  const path = e.composedPath();
693
875
  if (path.length) {
694
876
  retarget(path[0]);
@@ -718,7 +900,13 @@ function insertExpression(parent, value, current, marker) {
718
900
  const tc = typeof current;
719
901
  if (tc === "string" || tc === "number") {
720
902
  parent.firstChild.data = value;
721
- } else parent.textContent = value;
903
+ } else {
904
+ const owned = ownedChildCount(current);
905
+ if (owned === -1 || owned === parent.childNodes.length) parent.textContent = value;else {
906
+ removeOwnedChildren(parent, current);
907
+ parent.insertBefore(document.createTextNode(value), parent.firstChild);
908
+ }
909
+ }
722
910
  } else if (value === undefined) {
723
911
  cleanChildren(parent, current, marker);
724
912
  } else if (value.nodeType) {
@@ -741,7 +929,7 @@ function insertExpression(parent, value, current, marker) {
741
929
  appendNodes(parent, value, marker);
742
930
  } else reconcileArrays(parent, current, value, marker);
743
931
  } else {
744
- current && cleanChildren(parent);
932
+ current && cleanChildren(parent, current);
745
933
  appendNodes(parent, value);
746
934
  }
747
935
  } else ;
@@ -781,8 +969,31 @@ function appendNodes(parent, array, marker = null) {
781
969
  if (marker) n[$$SLOT] = marker;
782
970
  }
783
971
  }
972
+ function ownedChildCount(current) {
973
+ if (Array.isArray(current)) return current.length;
974
+ if (current == null) return -1;
975
+ if (current === "") return 0;
976
+ return 1;
977
+ }
978
+ function removeOwnedChildren(parent, current) {
979
+ if (Array.isArray(current)) {
980
+ for (let i = 0; i < current.length; i++) {
981
+ const el = current[i];
982
+ if (el.parentNode === parent) el.remove();
983
+ }
984
+ } else if (current.nodeType) {
985
+ if (current.parentNode === parent) current.remove();
986
+ } else {
987
+ const first = parent.firstChild;
988
+ if (first && first.nodeType === 3) first.remove();
989
+ }
990
+ }
784
991
  function cleanChildren(parent, current, marker, replacement) {
785
- if (marker === undefined) return parent.textContent = "";
992
+ if (marker === undefined) {
993
+ const owned = ownedChildCount(current);
994
+ if (owned === -1 || owned === parent.childNodes.length) return parent.textContent = "";
995
+ return removeOwnedChildren(parent, current);
996
+ }
786
997
  if (current.length) {
787
998
  let inserted = false;
788
999
  for (let i = current.length - 1; i >= 0; i--) {
@@ -871,9 +1082,10 @@ function Portal(props) {
871
1082
  return () => {
872
1083
  dispose();
873
1084
  let c = startMarker;
874
- while (c && c !== endMarker) {
1085
+ while (c) {
875
1086
  const n = c.nextSibling;
876
1087
  m.removeChild(c);
1088
+ if (c === endMarker) break;
877
1089
  c = n;
878
1090
  }
879
1091
  };
@@ -917,4 +1129,4 @@ function createElement(tagName, is = undefined) {
917
1129
  });
918
1130
  }
919
1131
 
920
- export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
1132
+ export { voidFn as Assets, ChildProperties, DOMElements, DOMWithState, DelegatedEvents, Dynamic, voidFn as HydrationScript, MathMLElements, Namespaces, Portal, RawTextElements, RequestContext, SVGElements, VoidElements, acquireAsset, addEvent, applyRef, assign, className, delegateEvents, dynamic, dynamicProperty, effect, escape, voidFn as generateHydrationScript, voidFn as getAssets, getDelegatedRoot, getFirstChild, getHydrationKey, getNextElement, getNextMarker, getNextMatch, getNextSibling, voidFn as getRequestEvent, hydrate, insert, isDev, isServer, memo, mergeProps, ref, registerDelegatedContainer, registerDelegatedRoot, render, renderToStream, renderToString, renderToStringAsync, resolveSSRNode, runHydrationEvents, scope, setAttribute, setAttributeNS, setProperty, setStyleProperty, spread, ssr, ssrAttribute, ssrClassList, ssrElement, ssrHydrationKey, ssrStyle, style, template, unregisterDelegatedContainer, unregisterDelegatedRoot, voidFn as useAssets };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@solidjs/web",
3
3
  "description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
4
- "version": "2.0.0-beta.15",
4
+ "version": "2.0.0-beta.17",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -137,10 +137,10 @@
137
137
  "seroval-plugins": "^1.1.0"
138
138
  },
139
139
  "peerDependencies": {
140
- "solid-js": "^2.0.0-beta.15"
140
+ "solid-js": "^2.0.0-beta.17"
141
141
  },
142
142
  "devDependencies": {
143
- "solid-js": "2.0.0-beta.15"
143
+ "solid-js": "2.0.0-beta.17"
144
144
  },
145
145
  "scripts": {
146
146
  "build": "npm-run-all -nl build:clean types:copy-jsx build:js",
@@ -149,9 +149,9 @@
149
149
  "link": "symlink-dir . node_modules/@solidjs/web",
150
150
  "types": "npm-run-all -nl types:clean types:copy-jsx types:web types:copy-web types:web-storage types:cjs",
151
151
  "types:clean": "rimraf types/ types-cjs/ storage/types-cjs/",
152
- "types:copy-jsx": "ncp ../../node_modules/dom-expressions/src/jsx.d.ts ./src/jsx.d.ts && ncp ../../node_modules/dom-expressions/src/jsx-properties.d.ts ./src/jsx-properties.d.ts && dom-expressions-jsx-types --input ./src/jsx.d.ts --element \"SolidElement | Node | ArrayElement\" --import 'import type { Element as SolidElement } from \"solid-js\";'",
152
+ "types:copy-jsx": "ncp ../../node_modules/@dom-expressions/runtime/src/jsx.d.ts ./src/jsx.d.ts && ncp ../../node_modules/@dom-expressions/runtime/src/jsx-properties.d.ts ./src/jsx-properties.d.ts && dom-expressions-jsx-types --input ./src/jsx.d.ts --element \"SolidElement | Node | ArrayElement\" --import 'import type { Element as SolidElement } from \"solid-js\";'",
153
153
  "types:web": "tsc --project ./tsconfig.build.json",
154
- "types:copy-web": "ncp ../../node_modules/dom-expressions/src/client.d.ts ./types/client.d.ts && ncp ../../node_modules/dom-expressions/src/server.d.ts ./types/server.d.ts && ncp ./src/jsx.d.ts ./types/jsx.d.ts && ncp ./src/jsx-properties.d.ts ./types/jsx-properties.d.ts",
154
+ "types:copy-web": "ncp ../../node_modules/@dom-expressions/runtime/src/client.d.ts ./types/client.d.ts && ncp ../../node_modules/@dom-expressions/runtime/src/server.d.ts ./types/server.d.ts && ncp ./src/jsx.d.ts ./types/jsx.d.ts && ncp ./src/jsx-properties.d.ts ./types/jsx-properties.d.ts",
155
155
  "types:web-storage": "tsc --project ./storage/tsconfig.build.json",
156
156
  "types:cjs": "node ../../scripts/sync-dual-types.mjs ./types ./types-cjs ./storage/types ./storage/types-cjs",
157
157
  "test": "vitest run && vitest run --config vite.config.server.mjs && vitest run --config vite.config.hydrate.mjs",
@@ -1 +1 @@
1
- export * from "dom-expressions/src/client.js";
1
+ export * from "@dom-expressions/runtime/src/client.js";
@@ -1 +1 @@
1
- export * from "dom-expressions/src/client.js";
1
+ export * from "@dom-expressions/runtime/src/client.js";
package/types/client.d.ts CHANGED
@@ -23,6 +23,7 @@ export function render(
23
23
  * - `2` — the template html is wrapped; the outer tag is stripped at clone time.
24
24
  */
25
25
  export function template(html: string, flag?: 1 | 2): () => Element;
26
+ export function scope<T extends () => any>(fn: T): T;
26
27
  export function effect<T>(fn: (prev?: T) => T, effect: (value: T, prev?: T) => void): void;
27
28
  export function memo<T>(fn: () => T, equal: boolean): () => T;
28
29
  export function untrack<T>(fn: () => T): T;
@@ -102,6 +103,19 @@ export function getNextMatch(start: Node, elementName: string): Element;
102
103
  export function getNextMarker(start: Node): [Node, Array<Node>];
103
104
  export function useAssets(fn: () => JSX.Element): void;
104
105
  export function getAssets(): string;
106
+ export type AssetDescriptor =
107
+ | { type: "style"; href: string; attrs?: Record<string, string> }
108
+ | { type: "inline-style"; id: string; content?: string; attrs?: Record<string, string> }
109
+ | { type: "module"; href: string }
110
+ | ExclusiveAssetDescriptor<any>;
111
+ export interface ExclusiveAssetDescriptor<T> {
112
+ policy: "exclusive";
113
+ key: string;
114
+ value: T;
115
+ get(): T;
116
+ set(value: T): void;
117
+ }
118
+ export function acquireAsset(descriptor: AssetDescriptor): () => void;
105
119
  export function HydrationScript(props?: { nonce?: string; eventNames?: string[] }): JSX.Element;
106
120
  export function generateHydrationScript(options?: {
107
121
  nonce?: string;
package/types/core.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { getOwner, runWithOwner, createComponent, createRoot as root, sharedConfig, untrack, merge as mergeProps, flatten, ssrHandleError } from "solid-js";
1
+ export { getOwner, runWithOwner, createComponent, createRoot as root, sharedConfig, untrack, merge as mergeProps, flatten, ssrHandleError, ssrScope } from "solid-js";
2
2
  export declare const effect: (fn: any, effectFn: any, options: any) => void;
3
3
  export declare const memo: (fn: any) => import("solid-js").SourceAccessor<any>;
package/types/server.d.ts CHANGED
@@ -75,6 +75,7 @@ export function ssrStyle(value: string | { [k: string]: string }): string;
75
75
  export function ssrStyleProperty(name: string, value: any): string;
76
76
  export function ssrAttribute(key: string, value: any): string;
77
77
  export function ssrGroup<T extends () => any[]>(fn: T, n: number): T;
78
+ export function scope<T>(fn: () => T): () => unknown;
78
79
  export function ssrHydrationKey(): string;
79
80
  export function resolveSSRNode(node: any, result?: any, top?: boolean): any;
80
81
  export function escape(s: any, attr?: boolean): any;
@@ -191,3 +192,5 @@ export function ref(
191
192
  ): void;
192
193
  /** @deprecated not supported on the server side */
193
194
  export function setStyleProperty(node: Element, name: string, value: any): void;
195
+ /** @deprecated not supported on the server side — register assets through the render context instead */
196
+ export function acquireAsset(descriptor: unknown): () => void;
@@ -23,6 +23,7 @@ export function render(
23
23
  * - `2` — the template html is wrapped; the outer tag is stripped at clone time.
24
24
  */
25
25
  export function template(html: string, flag?: 1 | 2): () => Element;
26
+ export function scope<T extends () => any>(fn: T): T;
26
27
  export function effect<T>(fn: (prev?: T) => T, effect: (value: T, prev?: T) => void): void;
27
28
  export function memo<T>(fn: () => T, equal: boolean): () => T;
28
29
  export function untrack<T>(fn: () => T): T;
@@ -102,6 +103,19 @@ export function getNextMatch(start: Node, elementName: string): Element;
102
103
  export function getNextMarker(start: Node): [Node, Array<Node>];
103
104
  export function useAssets(fn: () => JSX.Element): void;
104
105
  export function getAssets(): string;
106
+ export type AssetDescriptor =
107
+ | { type: "style"; href: string; attrs?: Record<string, string> }
108
+ | { type: "inline-style"; id: string; content?: string; attrs?: Record<string, string> }
109
+ | { type: "module"; href: string }
110
+ | ExclusiveAssetDescriptor<any>;
111
+ export interface ExclusiveAssetDescriptor<T> {
112
+ policy: "exclusive";
113
+ key: string;
114
+ value: T;
115
+ get(): T;
116
+ set(value: T): void;
117
+ }
118
+ export function acquireAsset(descriptor: AssetDescriptor): () => void;
105
119
  export function HydrationScript(props?: { nonce?: string; eventNames?: string[] }): JSX.Element;
106
120
  export function generateHydrationScript(options?: {
107
121
  nonce?: string;
@@ -1,3 +1,3 @@
1
- export { getOwner, runWithOwner, createComponent, createRoot as root, sharedConfig, untrack, merge as mergeProps, flatten, ssrHandleError } from "solid-js";
1
+ export { getOwner, runWithOwner, createComponent, createRoot as root, sharedConfig, untrack, merge as mergeProps, flatten, ssrHandleError, ssrScope } from "solid-js";
2
2
  export declare const effect: (fn: any, effectFn: any, options: any) => void;
3
3
  export declare const memo: (fn: any) => import("solid-js").SourceAccessor<any>;
@@ -75,6 +75,7 @@ export function ssrStyle(value: string | { [k: string]: string }): string;
75
75
  export function ssrStyleProperty(name: string, value: any): string;
76
76
  export function ssrAttribute(key: string, value: any): string;
77
77
  export function ssrGroup<T extends () => any[]>(fn: T, n: number): T;
78
+ export function scope<T>(fn: () => T): () => unknown;
78
79
  export function ssrHydrationKey(): string;
79
80
  export function resolveSSRNode(node: any, result?: any, top?: boolean): any;
80
81
  export function escape(s: any, attr?: boolean): any;
@@ -191,3 +192,5 @@ export function ref(
191
192
  ): void;
192
193
  /** @deprecated not supported on the server side */
193
194
  export function setStyleProperty(node: Element, name: string, value: any): void;
195
+ /** @deprecated not supported on the server side — register assets through the render context instead */
196
+ export function acquireAsset(descriptor: unknown): () => void;
@@ -1,2 +0,0 @@
1
- import type { RequestEvent } from "@solidjs/web";
2
- export declare function provideRequestEvent<T extends RequestEvent, U>(init: T, cb: () => U): U;
@@ -1,29 +0,0 @@
1
- import type { ArrayElement as SolidArrayElement, Element as SolidElement } from "solid-js";
2
- import type { JSX as DOMJSX } from "dom-expressions/src/jsx.js";
3
- export declare namespace JSX {
4
- type WithSolidChildren<T> = Omit<T, "children"> & {
5
- children?: Element;
6
- };
7
- export type Element = SolidElement;
8
- export interface ArrayElement extends SolidArrayElement {
9
- }
10
- export interface ElementClass extends DOMJSX.ElementClass {
11
- }
12
- export interface ElementAttributesProperty extends DOMJSX.ElementAttributesProperty {
13
- }
14
- export interface ElementChildrenAttribute extends DOMJSX.ElementChildrenAttribute {
15
- }
16
- export interface IntrinsicAttributes extends DOMJSX.IntrinsicAttributes {
17
- }
18
- export type IntrinsicElements = {
19
- [K in keyof DOMJSX.IntrinsicElements]: WithSolidChildren<DOMJSX.IntrinsicElements[K]>;
20
- };
21
- export type HTMLAttributes<T> = WithSolidChildren<DOMJSX.HTMLAttributes<T>>;
22
- export type SVGAttributes<T> = WithSolidChildren<DOMJSX.SVGAttributes<T>>;
23
- export type MathMLAttributes<T> = WithSolidChildren<DOMJSX.MathMLAttributes<T>>;
24
- export interface CustomEvents extends DOMJSX.CustomEvents {
25
- }
26
- export type EventHandler<T, E extends Event> = DOMJSX.EventHandler<T, E>;
27
- export type EventHandlerUnion<T, E extends Event> = DOMJSX.EventHandlerUnion<T, E>;
28
- export {};
29
- }
@@ -1,2 +0,0 @@
1
- import type { RequestEvent } from "@solidjs/web";
2
- export declare function provideRequestEvent<T extends RequestEvent, U>(init: T, cb: () => U): U;
@@ -1,29 +0,0 @@
1
- import type { ArrayElement as SolidArrayElement, Element as SolidElement } from "solid-js";
2
- import type { JSX as DOMJSX } from "dom-expressions/src/jsx.js";
3
- export declare namespace JSX {
4
- type WithSolidChildren<T> = Omit<T, "children"> & {
5
- children?: Element;
6
- };
7
- export type Element = SolidElement;
8
- export interface ArrayElement extends SolidArrayElement {
9
- }
10
- export interface ElementClass extends DOMJSX.ElementClass {
11
- }
12
- export interface ElementAttributesProperty extends DOMJSX.ElementAttributesProperty {
13
- }
14
- export interface ElementChildrenAttribute extends DOMJSX.ElementChildrenAttribute {
15
- }
16
- export interface IntrinsicAttributes extends DOMJSX.IntrinsicAttributes {
17
- }
18
- export type IntrinsicElements = {
19
- [K in keyof DOMJSX.IntrinsicElements]: WithSolidChildren<DOMJSX.IntrinsicElements[K]>;
20
- };
21
- export type HTMLAttributes<T> = WithSolidChildren<DOMJSX.HTMLAttributes<T>>;
22
- export type SVGAttributes<T> = WithSolidChildren<DOMJSX.SVGAttributes<T>>;
23
- export type MathMLAttributes<T> = WithSolidChildren<DOMJSX.MathMLAttributes<T>>;
24
- export interface CustomEvents extends DOMJSX.CustomEvents {
25
- }
26
- export type EventHandler<T, E extends Event> = DOMJSX.EventHandler<T, E>;
27
- export type EventHandlerUnion<T, E extends Event> = DOMJSX.EventHandlerUnion<T, E>;
28
- export {};
29
- }