solid-js 2.0.0-beta.12 → 2.0.0-beta.13

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/CHEATSHEET.md CHANGED
@@ -216,9 +216,12 @@ const rest = omit(props, "class", "style"); // replaces splitProps
216
216
  const user = createMemo(() => fetchUser(id()));
217
217
  // Reading user() suspends until ready; wrap in <Loading>.
218
218
 
219
- // "Refreshing…" indicator (false during initial Loading)
219
+ // "Refreshing…" indicator (false on the Loading path)
220
220
  isPending(() => user());
221
221
 
222
+ // Render guard: pending read follows the Loading path
223
+ isPending(() => user(), true);
224
+
222
225
  // Peek at the in-flight value during a transition
223
226
  latest(id);
224
227
 
@@ -290,7 +293,7 @@ Optimistic writes revert when the transition completes.
290
293
  </Loading>
291
294
 
292
295
  // Error boundary (replaces <ErrorBoundary>)
293
- <Errored fallback={(err, reset) => <button onClick={reset}>retry</button>}>
296
+ <Errored fallback={(err, reset) => <button onClick={reset}>retry {String(err())}</button>}>
294
297
  <Page />
295
298
  </Errored>
296
299
 
@@ -435,7 +438,15 @@ function titleDirective(source) {
435
438
  <some-element enabled="true" /> // when platform requires the string
436
439
  ```
437
440
 
438
- Lowercase HTML attribute names. No `attr:` / `bool:` / `oncapture:` namespaces. Event handlers stay camelCase (`onClick`).
441
+ Lowercase HTML attribute names. No `attr:` / `bool:` / `on:` / `oncapture:` namespaces. Event handlers stay camelCase (`onClick`).
442
+
443
+ For native listener options, use a ref callback:
444
+
445
+ ```jsx
446
+ const on = (type, handler, options) => el => el.addEventListener(type, handler, options);
447
+
448
+ <button ref={on("click", handleClick, { capture: true })} />;
449
+ ```
439
450
 
440
451
  ### Conditional classes — always use the array/object form
441
452
 
@@ -608,7 +619,7 @@ If your training data is 1.x, these are the corrections. **Read this before gene
608
619
  | `indexArray` | `mapArray` (handles non-keyed too) |
609
620
  | `use:foo={x}` directives | `ref={foo(x)}` (or array `ref={[a, b(x)]}`) |
610
621
  | `attr:` / `bool:` namespaces | Standard attribute behavior |
611
- | `oncapture:` | `addEventListener(..., { capture: true })` |
622
+ | `on:` / `oncapture:` | `onClick` for Solid events; ref callbacks for native listener opts |
612
623
  | `resetErrorBoundaries` | Boundaries heal automatically |
613
624
 
614
625
  ### Behavior changes
@@ -623,8 +634,8 @@ If your training data is 1.x, these are the corrections. **Read this before gene
623
634
  - **`<Show>` / `<Match>` function children narrow values** — non-keyed children receive accessors; keyed children receive raw values.
624
635
  - **Stores: setters take a draft callback** — mutate the draft in place by default. Returning a new value is shallow (array index-replace, object top-level diff); reach for it for filter/remove. Keyed reconcile is a _projection-fn_ feature, not a setter feature.
625
636
  - **`undefined` is a real value in `merge`** — it overrides rather than "skip this key".
626
- - **Async lives in computations** — return a Promise/AsyncIterable from `createMemo`/`createStore(fn)`/`createProjection`. Reads suspend; wrap in `<Loading>`.
627
- - **`Loading` is initial-only by default** — once content has rendered, revalidation keeps it visible. Use `isPending(() => x())` for "refreshing…" indicators. Use `<Loading on={key}>` to re-show fallback on key changes.
637
+ - **Async lives in computations** — return a Promise/AsyncIterable from `createMemo`/`createStore(fn)`/`createProjection`. Pending reads participate in `<Loading>`.
638
+ - **`Loading` covers unresolved branches** — once content has rendered, revalidation keeps it visible. Use `isPending(() => x())` for "refreshing…" indicators, or `isPending(() => x(), true)` when a render guard should follow the Loading path. Use `<Loading on={key}>` to re-show fallback on key changes.
628
639
  - **No `Suspense.Provider` or single error path** — async errors flow to `<Errored>` (or effect `error`); no inline `resource.error` branching.
629
640
  - **`createRoot` is owned by parent by default** — disposed when parent disposes. To detach: `runWithOwner(null, fn)`.
630
641
  - **Refs are functions** — `ref={el => ...}`. No `useRef`-style ref objects. Compose with arrays: `ref={[a, b]}`.
package/dist/dev.cjs CHANGED
@@ -869,7 +869,7 @@ function Match(props) {
869
869
  function Errored(props) {
870
870
  return createErrorBoundary(() => props.children, (err, reset) => {
871
871
  const f = props.fallback;
872
- if ((typeof f !== "function" || f.length == 0)) console.error(err);
872
+ if ((typeof f !== "function" || f.length == 0)) console.error(err());
873
873
  return typeof f === "function" && f.length ? f(err, reset) : f;
874
874
  });
875
875
  }
package/dist/dev.js CHANGED
@@ -868,7 +868,7 @@ function Match(props) {
868
868
  function Errored(props) {
869
869
  return createErrorBoundary(() => props.children, (err, reset) => {
870
870
  const f = props.fallback;
871
- if ((typeof f !== "function" || f.length == 0)) console.error(err);
871
+ if ((typeof f !== "function" || f.length == 0)) console.error(err());
872
872
  return typeof f === "function" && f.length ? f(err, reset) : f;
873
873
  });
874
874
  }
package/dist/server.cjs CHANGED
@@ -883,8 +883,8 @@ function createErrorBoundary(fn, fallback) {
883
883
  };
884
884
  const renderFallback = err => ctx ? runWithOwner(parent, () => {
885
885
  const fallbackOwner = createOwner();
886
- return runWithOwner(fallbackOwner, () => fallback(err, () => {}));
887
- }) : fallback(err, () => {});
886
+ return runWithOwner(fallbackOwner, () => fallback(() => err, () => {}));
887
+ }) : fallback(() => err, () => {});
888
888
  const serializeError = err => {
889
889
  if (ctx && owner.id && !runWithOwner(owner, () => getContext(NoHydrateContext))) {
890
890
  ctx.serialize(owner.id, err);
@@ -934,15 +934,13 @@ function flush() {}
934
934
  function resolve(fn) {
935
935
  throw new Error("resolve is not implemented on the server");
936
936
  }
937
- function isPending(fn, fallback) {
937
+ function isPending(fn, loading) {
938
938
  try {
939
939
  fn();
940
940
  return false;
941
941
  } catch (err) {
942
- if (err instanceof signals.NotReadyError && arguments.length > 1) {
943
- return fallback;
944
- }
945
- throw err;
942
+ if (!(err instanceof signals.NotReadyError) || loading) throw err;
943
+ return false;
946
944
  }
947
945
  }
948
946
  function latest(fn) {
package/dist/server.js CHANGED
@@ -882,8 +882,8 @@ function createErrorBoundary(fn, fallback) {
882
882
  };
883
883
  const renderFallback = err => ctx ? runWithOwner(parent, () => {
884
884
  const fallbackOwner = createOwner();
885
- return runWithOwner(fallbackOwner, () => fallback(err, () => {}));
886
- }) : fallback(err, () => {});
885
+ return runWithOwner(fallbackOwner, () => fallback(() => err, () => {}));
886
+ }) : fallback(() => err, () => {});
887
887
  const serializeError = err => {
888
888
  if (ctx && owner.id && !runWithOwner(owner, () => getContext(NoHydrateContext))) {
889
889
  ctx.serialize(owner.id, err);
@@ -933,15 +933,13 @@ function flush() {}
933
933
  function resolve(fn) {
934
934
  throw new Error("resolve is not implemented on the server");
935
935
  }
936
- function isPending(fn, fallback) {
936
+ function isPending(fn, loading) {
937
937
  try {
938
938
  fn();
939
939
  return false;
940
940
  } catch (err) {
941
- if (err instanceof NotReadyError && arguments.length > 1) {
942
- return fallback;
943
- }
944
- throw err;
941
+ if (!(err instanceof NotReadyError) || loading) throw err;
942
+ return false;
945
943
  }
946
944
  }
947
945
  function latest(fn) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-js",
3
3
  "description": "Reactive JavaScript library for building user interfaces. Compiles JSX to real DOM with fine-grained signal-based updates — no virtual DOM.",
4
- "version": "2.0.0-beta.12",
4
+ "version": "2.0.0-beta.13",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -107,7 +107,7 @@
107
107
  "performance"
108
108
  ],
109
109
  "dependencies": {
110
- "@solidjs/signals": "^2.0.0-beta.12",
110
+ "@solidjs/signals": "^2.0.0-beta.13",
111
111
  "csstype": "^3.1.0",
112
112
  "seroval": "~1.5.0",
113
113
  "seroval-plugins": "~1.5.0"
@@ -2,6 +2,7 @@ import type { Accessor, RevealOrder } from "@solidjs/signals";
2
2
  export type { RevealOrder };
3
3
  import type { Element as SolidElement } from "../types.js";
4
4
  type NonZeroParams<T extends (...args: any[]) => any> = Parameters<T>["length"] extends 0 ? never : T;
5
+ type ErrorAccessor = Accessor<unknown>;
5
6
  type ConditionalRenderCallback<T> = (item: Accessor<NonNullable<T>>) => SolidElement;
6
7
  type KeyedConditionalRenderCallback<T> = (item: NonNullable<T>) => SolidElement;
7
8
  type ConditionalRenderChildren<T, F extends ConditionalRenderCallback<T> = ConditionalRenderCallback<T>> = SolidElement | NonZeroParams<F>;
@@ -193,7 +194,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
193
194
  * @example
194
195
  * ```tsx
195
196
  * <Errored fallback={(err, reset) => (
196
- * <div onClick={reset}>Error: {err.toString()}</div>
197
+ * <div onClick={reset}>Error: {err().toString()}</div>
197
198
  * )}>
198
199
  * <MyComp />
199
200
  * </Errored>
@@ -202,7 +203,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
202
203
  * @description https://docs.solidjs.com/reference/components/error-boundary
203
204
  */
204
205
  export declare function Errored(props: {
205
- fallback: SolidElement | ((err: any, reset: () => void) => SolidElement);
206
+ fallback: SolidElement | ((err: ErrorAccessor, reset: () => void) => SolidElement);
206
207
  children: SolidElement;
207
208
  }): SolidElement;
208
209
  /**
@@ -1,4 +1,4 @@
1
- import { createErrorBoundary as coreErrorBoundary, createRenderEffect as coreRenderEffect, createEffect as coreEffect, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type Context } from "@solidjs/signals";
1
+ import { createRenderEffect as coreRenderEffect, createEffect as coreEffect, type Accessor, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type Context } from "@solidjs/signals";
2
2
  import type { Element as SolidElement } from "../types.js";
3
3
  type HydrationSsrFields = {
4
4
  /**
@@ -201,8 +201,8 @@ export declare const createSignal: {
201
201
  /**
202
202
  * Lower-level primitive that backs the `<Errored>` flow control.
203
203
  * Catches errors thrown inside `fn` and renders `fallback(error,
204
- * reset)` instead. `reset()` recomputes the failing sources so the
205
- * boundary can attempt to recover.
204
+ * reset)` instead. `error` is an accessor for the latest captured error;
205
+ * `reset()` recomputes the failing sources so the boundary can attempt to recover.
206
206
  *
207
207
  * App code should use `<Errored fallback={...}>` directly — reach for
208
208
  * this only when authoring a custom boundary component.
@@ -216,20 +216,20 @@ export declare const createSignal: {
216
216
  * // Custom boundary built on the primitive — adds telemetry around the
217
217
  * // canonical `<Errored>` shape.
218
218
  * function TracedErrored(props: {
219
- * fallback: (e: unknown) => JSX.Element;
219
+ * fallback: (e: () => unknown) => JSX.Element;
220
220
  * children: JSX.Element;
221
221
  * }): JSX.Element {
222
222
  * return createErrorBoundary(
223
223
  * () => props.children,
224
224
  * (err, reset) => {
225
- * reportError(err);
225
+ * reportError(err());
226
226
  * return props.fallback(err);
227
227
  * }
228
228
  * ) as unknown as JSX.Element;
229
229
  * }
230
230
  * ```
231
231
  */
232
- export declare const createErrorBoundary: typeof coreErrorBoundary;
232
+ export declare const createErrorBoundary: <U>(fn: () => any, fallback: (error: Accessor<unknown>, reset: () => void) => U) => () => unknown;
233
233
  /**
234
234
  * Creates an optimistic signal — a `Signal<T>` whose writes are
235
235
  * tentative inside an `action` transition: they show up immediately,
@@ -112,7 +112,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
112
112
  * @description https://docs.solidjs.com/reference/components/error-boundary
113
113
  */
114
114
  export declare function Errored(props: {
115
- fallback: SolidElement | ((err: any, reset: () => void) => SolidElement);
115
+ fallback: SolidElement | ((err: () => any, reset: () => void) => SolidElement);
116
116
  children: SolidElement;
117
117
  }): SolidElement;
118
118
  /**
@@ -111,7 +111,7 @@ declare const ErrorContext: Context<((err: any) => void) | null>;
111
111
  export { ErrorContext };
112
112
  export declare function runWithBoundaryErrorContext<T>(owner: Owner, render: () => T, onError: (err: any, parentHandler: ((err: any) => void) | null) => void, context?: NonNullable<typeof sharedConfig.context>, boundaryId?: string): T;
113
113
  export { NoHydrateContext };
114
- export declare function createErrorBoundary<U>(fn: () => any, fallback: (error: unknown, reset: () => void) => U): () => unknown;
114
+ export declare function createErrorBoundary<U>(fn: () => any, fallback: (error: Accessor<unknown>, reset: () => void) => U): () => unknown;
115
115
  export declare function createLoadingBoundary(fn: () => any, fallback: () => any, options?: {
116
116
  on?: () => any;
117
117
  }): () => unknown;
@@ -123,7 +123,7 @@ export declare function createRevealOrder<T>(fn: () => T, _options?: {
123
123
  export declare function untrack<T>(fn: () => T): T;
124
124
  export declare function flush(): void;
125
125
  export declare function resolve<T>(fn: () => T): Promise<T>;
126
- export declare function isPending(fn: () => any, fallback?: boolean): boolean;
126
+ export declare function isPending(fn: () => any, loading?: boolean): boolean;
127
127
  export declare function latest<T>(fn: () => T): T;
128
128
  export declare function isRefreshing(): boolean;
129
129
  export declare function refresh<T>(_target: Refreshable<T>): void;
@@ -2,6 +2,7 @@ import type { Accessor, RevealOrder } from "@solidjs/signals";
2
2
  export type { RevealOrder };
3
3
  import type { Element as SolidElement } from "../types.cjs";
4
4
  type NonZeroParams<T extends (...args: any[]) => any> = Parameters<T>["length"] extends 0 ? never : T;
5
+ type ErrorAccessor = Accessor<unknown>;
5
6
  type ConditionalRenderCallback<T> = (item: Accessor<NonNullable<T>>) => SolidElement;
6
7
  type KeyedConditionalRenderCallback<T> = (item: NonNullable<T>) => SolidElement;
7
8
  type ConditionalRenderChildren<T, F extends ConditionalRenderCallback<T> = ConditionalRenderCallback<T>> = SolidElement | NonZeroParams<F>;
@@ -193,7 +194,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
193
194
  * @example
194
195
  * ```tsx
195
196
  * <Errored fallback={(err, reset) => (
196
- * <div onClick={reset}>Error: {err.toString()}</div>
197
+ * <div onClick={reset}>Error: {err().toString()}</div>
197
198
  * )}>
198
199
  * <MyComp />
199
200
  * </Errored>
@@ -202,7 +203,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
202
203
  * @description https://docs.solidjs.com/reference/components/error-boundary
203
204
  */
204
205
  export declare function Errored(props: {
205
- fallback: SolidElement | ((err: any, reset: () => void) => SolidElement);
206
+ fallback: SolidElement | ((err: ErrorAccessor, reset: () => void) => SolidElement);
206
207
  children: SolidElement;
207
208
  }): SolidElement;
208
209
  /**
@@ -1,4 +1,4 @@
1
- import { createErrorBoundary as coreErrorBoundary, createRenderEffect as coreRenderEffect, createEffect as coreEffect, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type Context } from "@solidjs/signals";
1
+ import { createRenderEffect as coreRenderEffect, createEffect as coreEffect, type Accessor, type ComputeFunction, type MemoOptions, type NoInfer, type ProjectionOptions, type Refreshable, type Signal, type SignalOptions, type SourceAccessor, type Store, type StoreSetter, type Context } from "@solidjs/signals";
2
2
  import type { Element as SolidElement } from "../types.cjs";
3
3
  type HydrationSsrFields = {
4
4
  /**
@@ -201,8 +201,8 @@ export declare const createSignal: {
201
201
  /**
202
202
  * Lower-level primitive that backs the `<Errored>` flow control.
203
203
  * Catches errors thrown inside `fn` and renders `fallback(error,
204
- * reset)` instead. `reset()` recomputes the failing sources so the
205
- * boundary can attempt to recover.
204
+ * reset)` instead. `error` is an accessor for the latest captured error;
205
+ * `reset()` recomputes the failing sources so the boundary can attempt to recover.
206
206
  *
207
207
  * App code should use `<Errored fallback={...}>` directly — reach for
208
208
  * this only when authoring a custom boundary component.
@@ -216,20 +216,20 @@ export declare const createSignal: {
216
216
  * // Custom boundary built on the primitive — adds telemetry around the
217
217
  * // canonical `<Errored>` shape.
218
218
  * function TracedErrored(props: {
219
- * fallback: (e: unknown) => JSX.Element;
219
+ * fallback: (e: () => unknown) => JSX.Element;
220
220
  * children: JSX.Element;
221
221
  * }): JSX.Element {
222
222
  * return createErrorBoundary(
223
223
  * () => props.children,
224
224
  * (err, reset) => {
225
- * reportError(err);
225
+ * reportError(err());
226
226
  * return props.fallback(err);
227
227
  * }
228
228
  * ) as unknown as JSX.Element;
229
229
  * }
230
230
  * ```
231
231
  */
232
- export declare const createErrorBoundary: typeof coreErrorBoundary;
232
+ export declare const createErrorBoundary: <U>(fn: () => any, fallback: (error: Accessor<unknown>, reset: () => void) => U) => () => unknown;
233
233
  /**
234
234
  * Creates an optimistic signal — a `Signal<T>` whose writes are
235
235
  * tentative inside an `action` transition: they show up immediately,
@@ -112,7 +112,7 @@ export declare function Match<T>(props: AnyMatchProps<T>): SolidElement;
112
112
  * @description https://docs.solidjs.com/reference/components/error-boundary
113
113
  */
114
114
  export declare function Errored(props: {
115
- fallback: SolidElement | ((err: any, reset: () => void) => SolidElement);
115
+ fallback: SolidElement | ((err: () => any, reset: () => void) => SolidElement);
116
116
  children: SolidElement;
117
117
  }): SolidElement;
118
118
  /**
@@ -111,7 +111,7 @@ declare const ErrorContext: Context<((err: any) => void) | null>;
111
111
  export { ErrorContext };
112
112
  export declare function runWithBoundaryErrorContext<T>(owner: Owner, render: () => T, onError: (err: any, parentHandler: ((err: any) => void) | null) => void, context?: NonNullable<typeof sharedConfig.context>, boundaryId?: string): T;
113
113
  export { NoHydrateContext };
114
- export declare function createErrorBoundary<U>(fn: () => any, fallback: (error: unknown, reset: () => void) => U): () => unknown;
114
+ export declare function createErrorBoundary<U>(fn: () => any, fallback: (error: Accessor<unknown>, reset: () => void) => U): () => unknown;
115
115
  export declare function createLoadingBoundary(fn: () => any, fallback: () => any, options?: {
116
116
  on?: () => any;
117
117
  }): () => unknown;
@@ -123,7 +123,7 @@ export declare function createRevealOrder<T>(fn: () => T, _options?: {
123
123
  export declare function untrack<T>(fn: () => T): T;
124
124
  export declare function flush(): void;
125
125
  export declare function resolve<T>(fn: () => T): Promise<T>;
126
- export declare function isPending(fn: () => any, fallback?: boolean): boolean;
126
+ export declare function isPending(fn: () => any, loading?: boolean): boolean;
127
127
  export declare function latest<T>(fn: () => T): T;
128
128
  export declare function isRefreshing(): boolean;
129
129
  export declare function refresh<T>(_target: Refreshable<T>): void;