@_linked/react 1.2.1 → 1.3.0-next.20260605144237

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/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#13](https://github.com/linked-cm/react/pull/13) [`f4688d5`](https://github.com/linked-cm/react/commit/f4688d5c04f97070318f58fceae61d0280562b27) Thanks [@flyon](https://github.com/flyon)! - Loader / errorElement resolution chain, `_refresh` on `linkedSetComponent`, factory overloads, `LinkedInfinityLoader` opt-in export.
8
+
9
+ **New: factory overloads.** `linkedComponent` and `linkedSetComponent` now accept three forms:
10
+
11
+ ```ts
12
+ linkedComponent(query, fn); // existing
13
+ linkedComponent(query, fn, { loader, errorElement }); // new — positional options
14
+ linkedComponent({ query, component, loader, errorElement }); // new — config object
15
+ ```
16
+
17
+ **New: loader resolution.** Resolves in order — per-instance `loader={<X/>}` prop → factory `options.loader` → `LinkedComponentDefaults.loader` → built-in `<svg class="ld-loader"/>`. Apps style `.ld-loader` (default styles ship in `@_linked/css`'s `loader.css`) or replace the element via `LinkedComponentDefaults.loader = <MyLoader />`.
18
+
19
+ **New: error handling.** Both wrappers now capture query errors and resolve an `errorElement` in the same chain (per-instance prop → factory option → global default → built-in `<svg class="ld-error"/>`). Pass the sentinel `'rethrow'` (per-instance or as a global default) to let an external `<ErrorBoundary>` handle the error instead.
20
+
21
+ **New: `_refresh` on `linkedSetComponent`.** Mirrors the `linkedComponent` API — `_refresh()` re-runs the query, `_refresh(updatedProps)` patches local query-result state for optimistic UI.
22
+
23
+ **New: `LinkedInfinityLoader`.** Opt-in branded loader exported from `@_linked/react`. Tree-shake-safe via the package's new `sideEffects` array form.
24
+
25
+ **Tree-shaking.** `package.json` now declares `"sideEffects": ["./lib/cjs/package.js", "./lib/esm/package.js"]` so bundlers drop unused named exports (the package-registration module is whitelisted).
26
+
27
+ No breaking changes — all existing `linkedComponent(query, fn)` and `linkedSetComponent(query, fn)` call sites work unchanged.
28
+
3
29
  ## 1.2.1
4
30
 
5
31
  ### Patch Changes
package/README.md CHANGED
@@ -4,6 +4,8 @@ React bindings for `@_linked/core`.
4
4
 
5
5
  `@_linked/react` takes a Linked query from `@_linked/core`'s [Schema-Parameterized Query DSL](../core/README.md#schema-parameterized-query-dsl) and maps the top-level query result keys to props for a React component.
6
6
 
7
+ > **Query API note.** Queries are built with `Shape.select(...)` which returns a `QueryBuilder`. A `QueryBuilder` is **lazy** — it only fires when you `await` it or pass it through `linkedComponent` / `linkedSetComponent`. The old `Shape.query(...)` builder name is gone; use `.select(...)` everywhere.
8
+
7
9
  This package provides:
8
10
  - `linkedComponent(...)`
9
11
  - `linkedSetComponent(...)`
@@ -30,11 +32,11 @@ import {
30
32
 
31
33
  ### `linkedComponent(...)`
32
34
 
33
- `linkedComponent(...)` wraps a React component with a Linked query. You pass a query built with `Shape.query(...)` (which prepares query execution), not `Shape.select(...)` (which executes immediately). At render time, when you pass `of={{id: ...}}`, the wrapper applies the prepared query to that subject and injects the query result keys as props into your component.
35
+ `linkedComponent(...)` wraps a React component with a Linked query. You pass a query built with `Shape.select(...)` the returned `QueryBuilder` is lazy and the wrapper fires it at render time. When you pass `of={{id: ...}}`, the wrapper applies the prepared query to that subject and injects the query result keys as props into your component.
34
36
 
35
37
  ```tsx
36
38
  const PersonCard = linkedComponent(
37
- Person.query((p) => p.name),
39
+ Person.select((p) => p.name),
38
40
  ({name, source, _refresh}) => (
39
41
  <article>
40
42
  <h3>{name}</h3>
@@ -66,7 +68,7 @@ Example use case: optimistic UI after a mutation.
66
68
 
67
69
  ```tsx
68
70
  const PersonCard = linkedComponent(
69
- Person.query((p) => [p.name, p.active]),
71
+ Person.select((p) => [p.name, p.active]),
70
72
  ({id, name, active, _refresh, title}) => (
71
73
  <div>
72
74
  <h4>{title}</h4>
@@ -95,7 +97,7 @@ Use `linkedSetComponent(...)` when you want to render a list of sources.
95
97
 
96
98
  ```tsx
97
99
  const NameList = linkedSetComponent(
98
- Person.query((p) => p.name),
100
+ Person.select((p) => p.name),
99
101
  ({linkedData}) => (
100
102
  <ul>
101
103
  {(linkedData || []).map((person) => (
@@ -109,7 +111,7 @@ const NameList = linkedSetComponent(
109
111
  ### `linkedSetComponent(...)` (named data-prop format)
110
112
 
111
113
  ```tsx
112
- const personQuery = Person.query((p) => [p.name, p.hobby]);
114
+ const personQuery = Person.select((p) => [p.name, p.hobby]);
113
115
 
114
116
  const NameList = linkedSetComponent({persons: personQuery}, ({persons}) => (
115
117
  <ul>
@@ -153,7 +155,7 @@ Example:
153
155
  import React from 'react';
154
156
 
155
157
  const PeopleList = linkedSetComponent(
156
- Person.query((p) => [p.name]).limit(5),
158
+ Person.select((p) => [p.name]).limit(5),
157
159
  ({linkedData = [], query}) => {
158
160
  const [page, setPage] = React.useState(0);
159
161
 
@@ -4,3 +4,4 @@ export * from './utils/LinkedComponentClass.js';
4
4
  export * from './utils/Hooks.js';
5
5
  export * from './utils/ClassNames.js';
6
6
  export * from './utils/useQueryContext.js';
7
+ export { LinkedInfinityLoader } from './loaders/LinkedInfinityLoader.js';
package/lib/cjs/index.js CHANGED
@@ -14,10 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.LinkedInfinityLoader = void 0;
17
18
  __exportStar(require("./package.js"), exports);
18
19
  __exportStar(require("./utils/LinkedComponent.js"), exports);
19
20
  __exportStar(require("./utils/LinkedComponentClass.js"), exports);
20
21
  __exportStar(require("./utils/Hooks.js"), exports);
21
22
  __exportStar(require("./utils/ClassNames.js"), exports);
22
23
  __exportStar(require("./utils/useQueryContext.js"), exports);
24
+ var LinkedInfinityLoader_js_1 = require("./loaders/LinkedInfinityLoader.js");
25
+ Object.defineProperty(exports, "LinkedInfinityLoader", { enumerable: true, get: function () { return LinkedInfinityLoader_js_1.LinkedInfinityLoader; } });
23
26
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,6DAA2C;AAC3C,kEAAgD;AAChD,mDAAiC;AACjC,wDAAsC;AACtC,6DAA2C"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,+CAA6B;AAC7B,6DAA2C;AAC3C,kEAAgD;AAChD,mDAAiC;AACjC,wDAAsC;AACtC,6DAA2C;AAC3C,6EAAuE;AAA/D,+HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ /**
3
+ * Branded infinity-symbol loader. Opt-in: set
4
+ * `LinkedComponentDefaults.loader = <LinkedInfinityLoader />` to use it as
5
+ * the app-wide loading element, or pass `<X loader={<LinkedInfinityLoader/>}/>`
6
+ * per-instance.
7
+ *
8
+ * Uses `stroke: currentColor` and an animated `stroke-dashoffset` that
9
+ * traces along the figure-8 path. Styled by `.ld-loader--infinity` in
10
+ * `@_linked/css/loader.css`.
11
+ */
12
+ export declare function LinkedInfinityLoader(): React.ReactElement;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.LinkedInfinityLoader = LinkedInfinityLoader;
7
+ const react_1 = __importDefault(require("react"));
8
+ /**
9
+ * Branded infinity-symbol loader. Opt-in: set
10
+ * `LinkedComponentDefaults.loader = <LinkedInfinityLoader />` to use it as
11
+ * the app-wide loading element, or pass `<X loader={<LinkedInfinityLoader/>}/>`
12
+ * per-instance.
13
+ *
14
+ * Uses `stroke: currentColor` and an animated `stroke-dashoffset` that
15
+ * traces along the figure-8 path. Styled by `.ld-loader--infinity` in
16
+ * `@_linked/css/loader.css`.
17
+ */
18
+ function LinkedInfinityLoader() {
19
+ return (react_1.default.createElement("svg", { className: "ld-loader ld-loader--infinity", "aria-label": "Loading", role: "status", viewBox: "0 0 64 32", xmlns: "http://www.w3.org/2000/svg" },
20
+ react_1.default.createElement("path", { d: "M16 16 C 16 4, 30 4, 32 16 C 34 28, 48 28, 48 16 C 48 4, 34 4, 32 16 C 30 28, 16 28, 16 16 Z", fill: "none", stroke: "currentColor" })));
21
+ }
22
+ //# sourceMappingURL=LinkedInfinityLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkedInfinityLoader.js","sourceRoot":"","sources":["../../../src/loaders/LinkedInfinityLoader.tsx"],"names":[],"mappings":";;;;;AAYA,oDAgBC;AA5BD,kDAA0B;AAE1B;;;;;;;;;GASG;AACH,SAAgB,oBAAoB;IAClC,OAAO,CACL,uCACE,SAAS,EAAC,+BAA+B,gBAC9B,SAAS,EACpB,IAAI,EAAC,QAAQ,EACb,OAAO,EAAC,WAAW,EACnB,KAAK,EAAC,4BAA4B;QAElC,wCACE,CAAC,EAAC,8FAA8F,EAChG,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,GACrB,CACE,CACP,CAAC;AACJ,CAAC"}
@@ -3,8 +3,21 @@ declare const linkedUtil: (constructor: any) => any, linkedOntology: (allFileExp
3
3
  <T extends typeof Shape>(constructor: T): void;
4
4
  <T extends typeof Shape>(config?: import("@_linked/core/utils/Package").ShapeConfig): (constructor: T) => void;
5
5
  }, registerPackageExport: (exportedObject: any) => void, registerPackageModule: (_module: any) => void, packageExports: any, getPackageShape: (name: string) => import("@_linked/core/shapes/Shape").ShapeConstructor | undefined;
6
- declare const linkedComponent: <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any, infer R, any> ? R : QueryType extends import("@_linked/core/queries/FieldSet.js").FieldSet<infer R_1, any> ? R_1 : QueryType>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").QueryResponseToResultType<Res, ShapeType>, ShapeType>) => import("./utils/LinkedComponent.js").LinkedComponent<CustomProps, ShapeType, Res>;
7
- declare const linkedSetComponent: <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> | {
8
- [key: string]: import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any>;
9
- } = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = import("@_linked/core/queries/SelectQuery.js").ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableSetComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").GetCustomObjectKeys<QueryType> & import("@_linked/core/queries/SelectQuery.js").QueryControllerProps, ShapeType>) => import("./utils/LinkedComponent.js").LinkedSetComponent<CustomProps, ShapeType, Res>;
6
+ declare const linkedComponent: {
7
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any, infer R, any> ? R : QueryType extends import("@_linked/core/queries/FieldSet.js").FieldSet<infer R_1, any> ? R_1 : QueryType>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").QueryResponseToResultType<Res, ShapeType>, ShapeType>): import("./utils/LinkedComponent.js").LinkedComponent<CustomProps, ShapeType, Res>;
8
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any, infer R, any> ? R : QueryType extends import("@_linked/core/queries/FieldSet.js").FieldSet<infer R_1, any> ? R_1 : QueryType>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").QueryResponseToResultType<Res, ShapeType>, ShapeType>, options: import("./utils/LinkedComponent.js").LinkedComponentOptions): import("./utils/LinkedComponent.js").LinkedComponent<CustomProps, ShapeType, Res>;
9
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any, infer R, any> ? R : QueryType extends import("@_linked/core/queries/FieldSet.js").FieldSet<infer R_1, any> ? R_1 : QueryType>(config: import("./utils/LinkedComponent.js").LinkedComponentConfig<QueryType, CustomProps & import("@_linked/core/queries/SelectQuery.js").QueryResponseToResultType<Res, ShapeType>, ShapeType>): import("./utils/LinkedComponent.js").LinkedComponent<CustomProps, ShapeType, Res>;
10
+ };
11
+ declare const linkedSetComponent: {
12
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> | {
13
+ [key: string]: import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any>;
14
+ } = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = import("@_linked/core/queries/SelectQuery.js").ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableSetComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").GetCustomObjectKeys<QueryType> & import("@_linked/core/queries/SelectQuery.js").QueryControllerProps, ShapeType>): import("./utils/LinkedComponent.js").LinkedSetComponent<CustomProps, ShapeType, Res>;
15
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> | {
16
+ [key: string]: import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any>;
17
+ } = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = import("@_linked/core/queries/SelectQuery.js").ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: import("./utils/LinkedComponent.js").LinkableSetComponent<CustomProps & import("@_linked/core/queries/SelectQuery.js").GetCustomObjectKeys<QueryType> & import("@_linked/core/queries/SelectQuery.js").QueryControllerProps, ShapeType>, options: import("./utils/LinkedComponent.js").LinkedComponentOptions): import("./utils/LinkedComponent.js").LinkedSetComponent<CustomProps, ShapeType, Res>;
18
+ <QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any> | {
19
+ [key: string]: import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<any>;
20
+ } = null, CustomProps = {}, ShapeType extends Shape = QueryType extends import("@_linked/core/queries/QueryBuilder.js").QueryBuilder<infer S extends Shape, any, any> ? S : never, Res = import("@_linked/core/queries/SelectQuery.js").ToQueryResultSet<QueryType>>(config: import("./utils/LinkedComponent.js").LinkedSetComponentConfig<QueryType, CustomProps & import("@_linked/core/queries/SelectQuery.js").GetCustomObjectKeys<QueryType> & import("@_linked/core/queries/SelectQuery.js").QueryControllerProps, ShapeType>): import("./utils/LinkedComponent.js").LinkedSetComponent<CustomProps, ShapeType, Res>;
21
+ };
22
+ export declare const linkedPackage: (packageName: any) => any;
10
23
  export { linkedComponent, linkedSetComponent, linkedShape, linkedUtil, linkedOntology, registerPackageExport, registerPackageModule, packageExports, getPackageShape, };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPackageShape = exports.packageExports = exports.registerPackageModule = exports.registerPackageExport = exports.linkedOntology = exports.linkedUtil = exports.linkedShape = exports.linkedSetComponent = exports.linkedComponent = void 0;
3
+ exports.getPackageShape = exports.packageExports = exports.registerPackageModule = exports.registerPackageExport = exports.linkedOntology = exports.linkedUtil = exports.linkedShape = exports.linkedSetComponent = exports.linkedComponent = exports.linkedPackage = void 0;
4
4
  const CoreSet_1 = require("@_linked/core/collections/CoreSet");
5
5
  const Package_1 = require("@_linked/core/utils/Package");
6
6
  const LinkedComponent_js_1 = require("./utils/LinkedComponent.js");
@@ -30,4 +30,9 @@ const linkedComponent = (0, LinkedComponent_js_1.createLinkedComponentFn)(regist
30
30
  exports.linkedComponent = linkedComponent;
31
31
  const linkedSetComponent = (0, LinkedComponent_js_1.createLinkedSetComponentFn)(registerPackageExport, registerComponent);
32
32
  exports.linkedSetComponent = linkedSetComponent;
33
+ const linkedPackage = (packageName) => {
34
+ return Object.assign({ linkedComponent,
35
+ linkedSetComponent }, (0, exports.linkedPackage)(packageName));
36
+ };
37
+ exports.linkedPackage = linkedPackage;
33
38
  //# sourceMappingURL=package.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"package.js","sourceRoot":"","sources":["../../src/package.ts"],"names":[],"mappings":";;;AAAA,+DAA0D;AAC1D,yDAA0D;AAE1D,mEAIoC;AAEpC,IAAI,iBAAiB,GAA0C,IAAI,GAAG,EAAE,CAAC;AAEzE,MAAM,EACJ,UAAU,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,eAAe,GAChB,GAAG,IAAA,uBAAa,EAAC,gBAAgB,CAAC,CAAC;AAoClC,gCAAU;AACV,wCAAc;AAFd,kCAAW;AAGX,sDAAqB;AACrB,sDAAqB;AACrB,wCAAc;AACd,0CAAe;AAvCjB,SAAS,iBAAiB,CAAC,iBAA4B,EAAE,KAAoB;IAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE,CAAC;YACtE,OAAO,CAAC,IAAI,CACV,aACG,iBAAyB,CAAC,WAAW,IAAK,iBAAyB,CAAC,IACvE,4BAA4B,CAC7B,CAAC;YACF,OAAO;QACT,CAAC;QACD,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,iBAAO,EAAO,CAAC,CAAC;IACnD,CAAC;IAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,eAAe,GAAG,IAAA,4CAAuB,EAC7C,qBAAqB,EACrB,iBAAiB,CAClB,CAAC;AAQA,0CAAe;AANjB,MAAM,kBAAkB,GAAG,IAAA,+CAA0B,EACnD,qBAAqB,EACrB,iBAAiB,CAClB,CAAC;AAIA,gDAAkB"}
1
+ {"version":3,"file":"package.js","sourceRoot":"","sources":["../../src/package.ts"],"names":[],"mappings":";;;AAAA,+DAA0D;AAC1D,yDAA+E;AAE/E,mEAIoC;AAEpC,IAAI,iBAAiB,GAA0C,IAAI,GAAG,EAAE,CAAC;AAEzE,MAAM,EACJ,UAAU,EACV,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,eAAe,GAChB,GAAG,IAAA,uBAAiB,EAAC,gBAAgB,CAAC,CAAC;AA2CtC,gCAAU;AACV,wCAAc;AAFd,kCAAW;AAGX,sDAAqB;AACrB,sDAAqB;AACrB,wCAAc;AACd,0CAAe;AA9CjB,SAAS,iBAAiB,CAAC,iBAA4B,EAAE,KAAoB;IAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,EAAE,CAAC;YACtE,OAAO,CAAC,IAAI,CACV,aACG,iBAAyB,CAAC,WAAW,IAAK,iBAAyB,CAAC,IACvE,4BAA4B,CAC7B,CAAC;YACF,OAAO;QACT,CAAC;QACD,KAAK,GAAG,iBAAiB,CAAC,KAAK,CAAC;IAClC,CAAC;IAED,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QAClC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,iBAAO,EAAO,CAAC,CAAC;IACnD,CAAC;IAED,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,eAAe,GAAG,IAAA,4CAAuB,EAC7C,qBAAqB,EACrB,iBAAiB,CAClB,CAAC;AAeA,0CAAe;AAbjB,MAAM,kBAAkB,GAAG,IAAA,+CAA0B,EACnD,qBAAqB,EACrB,iBAAiB,CAClB,CAAC;AAWA,gDAAkB;AAVb,MAAM,aAAa,GAAG,CAAC,WAAW,EAAE,EAAE;IAC3C,uBACE,eAAe;QACf,kBAAkB,IACf,IAAA,qBAAa,EAAC,WAAW,CAAC,EAC9B;AACH,CAAC,CAAA;AANY,QAAA,aAAa,iBAMzB"}
@@ -36,6 +36,39 @@ export interface LinkedSetComponent<P, ShapeType extends Shape = Shape, Res = an
36
36
  shape?: typeof Shape;
37
37
  }
38
38
  export type LinkableComponent<P, ShapeType extends Shape = Shape> = React.FC<P & LinkedComponentProps<ShapeType>>;
39
+ /**
40
+ * Options accepted by both `linkedComponent` and `linkedSetComponent` at
41
+ * definition time (3rd positional arg) and inside the config-object form.
42
+ * `loader` replaces the framework's default loading element; `errorElement`
43
+ * replaces the default error element. Pass the sentinel `'rethrow'` for
44
+ * `errorElement` to let the error propagate to an external `<ErrorBoundary>`.
45
+ */
46
+ export interface LinkedComponentOptions {
47
+ loader?: React.ReactElement;
48
+ errorElement?: React.ReactElement | 'rethrow';
49
+ }
50
+ /**
51
+ * Config-object form of the factory:
52
+ * linkedComponent({ query, component, loader, errorElement });
53
+ */
54
+ export interface LinkedComponentConfig<Q, P, ShapeType extends Shape = Shape> extends LinkedComponentOptions {
55
+ query: Q;
56
+ component: LinkableComponent<P, ShapeType>;
57
+ }
58
+ export interface LinkedSetComponentConfig<Q, P, ShapeType extends Shape = Shape> extends LinkedComponentOptions {
59
+ query: Q;
60
+ component: LinkableSetComponent<P, ShapeType>;
61
+ }
62
+ /**
63
+ * App-global override for loader and errorElement. Setting either of these
64
+ * applies to every `linkedComponent` / `linkedSetComponent` that doesn't
65
+ * specify its own. Resolution order:
66
+ * instance prop > definition options > LinkedComponentDefaults > built-in
67
+ */
68
+ export declare const LinkedComponentDefaults: {
69
+ loader: React.ReactElement | undefined;
70
+ errorElement: React.ReactElement | 'rethrow' | undefined;
71
+ };
39
72
  export type LinkableSetComponent<P, ShapeType extends Shape = Shape, DataResultType = any> = React.FC<LinkedSetComponentProps<ShapeType, DataResultType> & P>;
40
73
  export interface LinkedSetComponentProps<ShapeType extends Shape, DataResultType = any> extends LinkedComponentBaseProps<DataResultType>, QueryControllerProps {
41
74
  sources: ShapeSet<ShapeType>;
@@ -56,14 +89,28 @@ export interface LinkedComponentInputProps<ShapeType extends Shape = Shape> exte
56
89
  interface LinkedComponentInputBaseProps extends React.PropsWithChildren {
57
90
  className?: string | string[];
58
91
  style?: React.CSSProperties;
92
+ loader?: React.ReactElement;
93
+ errorElement?: React.ReactElement | 'rethrow';
59
94
  }
60
95
  export type LinkedSetComponentFactoryFn = <QueryType extends QueryBuilder<any> | {
61
96
  [key: string]: QueryBuilder<any>;
62
97
  } = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = ToQueryResultSet<QueryType>>(requiredData: QueryType, functionalComponent: LinkableSetComponent<CustomProps & GetCustomObjectKeys<QueryType> & QueryControllerProps, ShapeType, Res>) => LinkedSetComponent<CustomProps, ShapeType, Res>;
63
98
  export type LinkedComponentFactoryFn = <QueryType extends QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Response = GetQueryResponseType<QueryType>, ResultType = QueryResponseToResultType<Response, ShapeType>>(query: QueryType, functionalComponent: LinkableComponent<CustomProps & ResultType, ShapeType>) => LinkedComponent<CustomProps, ShapeType, ResultType>;
64
- export declare function createLinkedComponentFn(registerPackageExport: any, registerComponent: any): <QueryType extends QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = GetQueryResponseType<QueryType>>(query: QueryType, functionalComponent: LinkableComponent<CustomProps & QueryResponseToResultType<Res, ShapeType>, ShapeType>) => LinkedComponent<CustomProps, ShapeType, Res>;
65
- export declare function createLinkedSetComponentFn(registerPackageExport: any, registerComponent: any): <QueryType extends QueryBuilder<any> | {
66
- [key: string]: QueryBuilder<any>;
67
- } = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: LinkableSetComponent<CustomProps & GetCustomObjectKeys<QueryType> & QueryControllerProps, ShapeType>) => LinkedSetComponent<CustomProps, ShapeType, Res>;
99
+ export declare function createLinkedComponentFn(registerPackageExport: any, registerComponent: any): {
100
+ <QueryType extends QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = GetQueryResponseType<QueryType>>(query: QueryType, functionalComponent: LinkableComponent<CustomProps & QueryResponseToResultType<Res, ShapeType>, ShapeType>): LinkedComponent<CustomProps, ShapeType, Res>;
101
+ <QueryType extends QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = GetQueryResponseType<QueryType>>(query: QueryType, functionalComponent: LinkableComponent<CustomProps & QueryResponseToResultType<Res, ShapeType>, ShapeType>, options: LinkedComponentOptions): LinkedComponent<CustomProps, ShapeType, Res>;
102
+ <QueryType extends QueryBuilder<any> = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = GetQueryResponseType<QueryType>>(config: LinkedComponentConfig<QueryType, CustomProps & QueryResponseToResultType<Res, ShapeType>, ShapeType>): LinkedComponent<CustomProps, ShapeType, Res>;
103
+ };
104
+ export declare function createLinkedSetComponentFn(registerPackageExport: any, registerComponent: any): {
105
+ <QueryType extends QueryBuilder<any> | {
106
+ [key: string]: QueryBuilder<any>;
107
+ } = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: LinkableSetComponent<CustomProps & GetCustomObjectKeys<QueryType> & QueryControllerProps, ShapeType>): LinkedSetComponent<CustomProps, ShapeType, Res>;
108
+ <QueryType extends QueryBuilder<any> | {
109
+ [key: string]: QueryBuilder<any>;
110
+ } = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = ToQueryResultSet<QueryType>>(query: QueryType, functionalComponent: LinkableSetComponent<CustomProps & GetCustomObjectKeys<QueryType> & QueryControllerProps, ShapeType>, options: LinkedComponentOptions): LinkedSetComponent<CustomProps, ShapeType, Res>;
111
+ <QueryType extends QueryBuilder<any> | {
112
+ [key: string]: QueryBuilder<any>;
113
+ } = null, CustomProps = {}, ShapeType extends Shape = GetQueryShapeType<QueryType>, Res = ToQueryResultSet<QueryType>>(config: LinkedSetComponentConfig<QueryType, CustomProps & GetCustomObjectKeys<QueryType> & QueryControllerProps, ShapeType>): LinkedSetComponent<CustomProps, ShapeType, Res>;
114
+ };
68
115
  export declare function getSourceFromInputProps(props: any, shapeClass: any): any;
69
116
  export {};
@@ -32,7 +32,19 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __rest = (this && this.__rest) || function (s, e) {
36
+ var t = {};
37
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
38
+ t[p] = s[p];
39
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
40
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
41
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
42
+ t[p[i]] = s[p[i]];
43
+ }
44
+ return t;
45
+ };
35
46
  Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.LinkedComponentDefaults = void 0;
36
48
  exports.createLinkedComponentFn = createLinkedComponentFn;
37
49
  exports.createLinkedSetComponentFn = createLinkedSetComponentFn;
38
50
  exports.getSourceFromInputProps = getSourceFromInputProps;
@@ -45,17 +57,39 @@ const Package_1 = require("@_linked/core/utils/Package");
45
57
  const ShapeSet_1 = require("@_linked/core/collections/ShapeSet");
46
58
  const NodeReference_1 = require("@_linked/core/utils/NodeReference");
47
59
  const ShapeClass_1 = require("@_linked/core/utils/ShapeClass");
60
+ /**
61
+ * App-global override for loader and errorElement. Setting either of these
62
+ * applies to every `linkedComponent` / `linkedSetComponent` that doesn't
63
+ * specify its own. Resolution order:
64
+ * instance prop > definition options > LinkedComponentDefaults > built-in
65
+ */
66
+ exports.LinkedComponentDefaults = {
67
+ loader: undefined,
68
+ errorElement: undefined,
69
+ };
48
70
  function createLinkedComponentFn(registerPackageExport, registerComponent) {
49
- return function linkedComponent(query, functionalComponent) {
71
+ function linkedComponent(arg1, arg2, arg3) {
72
+ const normalized = normalizeFactoryArgs(arg1, arg2, arg3);
73
+ const query = normalized.query;
74
+ const functionalComponent = normalized.component;
75
+ const options = normalized.options;
50
76
  let [shapeClass, actualQuery] = processQuery(query);
51
77
  let _wrappedComponent = react_1.default.forwardRef((props, ref) => {
52
78
  var _a;
53
79
  let [queryResult, setQueryResult] = (0, react_1.useState)(undefined);
54
80
  let [loadingData, setLoadingData] = (0, react_1.useState)();
81
+ let [queryError, setQueryError] = (0, react_1.useState)(undefined);
55
82
  let linkedProps = getLinkedComponentProps(props, shapeClass);
56
83
  if (ref) {
57
84
  linkedProps.ref = ref;
58
85
  }
86
+ // Strip framework-only input props before forwarding to the
87
+ // wrapped component — `loader` / `errorElement` aren't part of
88
+ // the user's render contract.
89
+ const instanceLoader = linkedProps.loader;
90
+ const instanceErrorElement = linkedProps.errorElement;
91
+ delete linkedProps.loader;
92
+ delete linkedProps.errorElement;
59
93
  const loadData = () => {
60
94
  var _a;
61
95
  const sourceId = (_a = linkedProps.source) === null || _a === void 0 ? void 0 : _a.id;
@@ -65,14 +99,18 @@ function createLinkedComponentFn(registerPackageExport, registerComponent) {
65
99
  ? actualQuery.for(linkedProps.source)
66
100
  : actualQuery;
67
101
  setLoadingData(sourceId || requestQuery.toJSON().subject);
68
- (0, queryDispatch_1.getQueryDispatch)().selectQuery(requestQuery.build()).then((result) => {
69
- // Use empty object when result is null/undefined so the component
70
- // renders with default values instead of showing spinner forever.
102
+ setQueryError(undefined);
103
+ (0, queryDispatch_1.getQueryDispatch)()
104
+ .selectQuery(requestQuery.build())
105
+ .then((result) => {
106
+ // Use empty object when result is null/undefined so the
107
+ // component renders with default values instead of
108
+ // showing the loader forever.
71
109
  setQueryResult(result !== null && result !== void 0 ? result : {});
72
110
  setLoadingData(null);
73
- }).catch((err) => {
74
- console.error('linkedComponent loadData failed:', err);
75
- setQueryResult({});
111
+ })
112
+ .catch((err) => {
113
+ setQueryError(err instanceof Error ? err : new Error(String(err)));
76
114
  setLoadingData(null);
77
115
  });
78
116
  }
@@ -102,8 +140,8 @@ function createLinkedComponentFn(registerPackageExport, registerComponent) {
102
140
  const resolvedSubjectId = actualQuery.toJSON().subject;
103
141
  if (!linkedProps.source && !resolvedSubjectId) {
104
142
  if (actualQuery.hasPendingContext()) {
105
- // Subject will resolve after auth — show spinner until then.
106
- return createLoadingSpinner();
143
+ // Subject will resolve after auth — show loader until then.
144
+ return resolveLoader(instanceLoader, options.loader);
107
145
  }
108
146
  console.warn('This component requires a source to be provided (use the property "of"): ' +
109
147
  functionalComponent.name);
@@ -114,17 +152,27 @@ function createLinkedComponentFn(registerPackageExport, registerComponent) {
114
152
  if (queryResult) {
115
153
  setQueryResult(undefined);
116
154
  }
155
+ if (queryError) {
156
+ setQueryError(undefined);
157
+ }
117
158
  if (usingStorage && !sourceIsValidQResult) {
118
159
  loadData();
119
160
  }
120
161
  }, [(_a = linkedProps.source) === null || _a === void 0 ? void 0 : _a.id, resolvedSubjectId]);
162
+ if (queryError) {
163
+ const resolved = resolveErrorElement(instanceErrorElement, options.errorElement);
164
+ if (resolved === 'rethrow') {
165
+ throw queryError;
166
+ }
167
+ return resolved;
168
+ }
121
169
  let dataIsLoaded = queryResult || !usingStorage || sourceIsValidQResult;
122
170
  // Keep legacy client-side guard to avoid hydration drift.
123
171
  if (dataIsLoaded && typeof window !== 'undefined') {
124
172
  return react_1.default.createElement(functionalComponent, linkedProps);
125
173
  }
126
174
  else {
127
- return createLoadingSpinner();
175
+ return resolveLoader(instanceLoader, options.loader);
128
176
  }
129
177
  });
130
178
  _wrappedComponent.original = functionalComponent;
@@ -138,15 +186,23 @@ function createLinkedComponentFn(registerPackageExport, registerComponent) {
138
186
  }
139
187
  registerComponent(_wrappedComponent, shapeClass);
140
188
  return _wrappedComponent;
141
- };
189
+ }
190
+ return linkedComponent;
142
191
  }
143
192
  function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
144
- return function linkedSetComponent(query, functionalComponent) {
193
+ function linkedSetComponent(arg1, arg2, arg3) {
194
+ const normalized = normalizeFactoryArgs(arg1, arg2, arg3);
195
+ const query = normalized.query;
196
+ const functionalComponent = normalized.component;
197
+ const options = normalized.options;
145
198
  let [shapeClass, actualQuery] = processQuery(query, true);
146
199
  let usingStorage = LinkedStorage_1.LinkedStorage.isInitialised();
147
200
  let _wrappedComponent = react_1.default.forwardRef((props, ref) => {
148
201
  var _a;
149
202
  let [queryResult, setQueryResult] = (0, react_1.useState)(undefined);
203
+ let [queryError, setQueryError] = (0, react_1.useState)(undefined);
204
+ // Bumped by `_refresh()` to force the load-effect to re-run.
205
+ let [refreshNonce, setRefreshNonce] = (0, react_1.useState)(0);
150
206
  let linkedProps = getLinkedSetComponentProps(props, shapeClass, functionalComponent);
151
207
  let defaultLimit = actualQuery.toJSON().limit || Package_1.DEFAULT_LIMIT;
152
208
  let [limit, setLimit] = (0, react_1.useState)(defaultLimit);
@@ -154,6 +210,10 @@ function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
154
210
  if (ref) {
155
211
  linkedProps.ref = ref;
156
212
  }
213
+ const instanceLoader = linkedProps.loader;
214
+ const instanceErrorElement = linkedProps.errorElement;
215
+ delete linkedProps.loader;
216
+ delete linkedProps.errorElement;
157
217
  let sourceIsValidQResult = Array.isArray(props.of) &&
158
218
  props.of.length > 0 &&
159
219
  typeof ((_a = props.of[0]) === null || _a === void 0 ? void 0 : _a.id) === 'string' &&
@@ -197,6 +257,17 @@ function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
197
257
  },
198
258
  };
199
259
  }
260
+ linkedProps._refresh = (0, react_1.useCallback)((updatedProps) => {
261
+ if (updatedProps) {
262
+ setQueryResult((current) => current ? Object.assign(Object.assign({}, current), updatedProps) : updatedProps);
263
+ }
264
+ else {
265
+ // Bump the nonce so the load-effect refires even when
266
+ // props.of / limit / offset are unchanged.
267
+ setQueryError(undefined);
268
+ setRefreshNonce((n) => n + 1);
269
+ }
270
+ }, []);
200
271
  (0, react_1.useEffect)(() => {
201
272
  if (usingStorage && !sourceIsValidQResult) {
202
273
  // QueryBuilder is immutable — chain calls to set subjects, limit, offset.
@@ -210,11 +281,24 @@ function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
210
281
  if (offset) {
211
282
  requestQuery = requestQuery.offset(offset);
212
283
  }
213
- (0, queryDispatch_1.getQueryDispatch)().selectQuery(requestQuery.build()).then((result) => {
284
+ setQueryError(undefined);
285
+ (0, queryDispatch_1.getQueryDispatch)()
286
+ .selectQuery(requestQuery.build())
287
+ .then((result) => {
214
288
  setQueryResult(result);
289
+ })
290
+ .catch((err) => {
291
+ setQueryError(err instanceof Error ? err : new Error(String(err)));
215
292
  });
216
293
  }
217
- }, [props.of, limit, offset]);
294
+ }, [props.of, limit, offset, refreshNonce]);
295
+ if (queryError) {
296
+ const resolved = resolveErrorElement(instanceErrorElement, options.errorElement);
297
+ if (resolved === 'rethrow') {
298
+ throw queryError;
299
+ }
300
+ return resolved;
301
+ }
218
302
  let dataIsLoaded = queryResult || !usingStorage || sourceIsValidQResult;
219
303
  if (typeof queryResult === 'undefined' &&
220
304
  usingStorage &&
@@ -225,7 +309,7 @@ function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
225
309
  return react_1.default.createElement(functionalComponent, linkedProps);
226
310
  }
227
311
  else {
228
- return createLoadingSpinner();
312
+ return resolveLoader(instanceLoader, options.loader);
229
313
  }
230
314
  });
231
315
  _wrappedComponent.original = functionalComponent;
@@ -239,7 +323,8 @@ function createLinkedSetComponentFn(registerPackageExport, registerComponent) {
239
323
  }
240
324
  registerComponent(_wrappedComponent, shapeClass);
241
325
  return _wrappedComponent;
242
- };
326
+ }
327
+ return linkedSetComponent;
243
328
  }
244
329
  function getLinkedComponentProps(props, shapeClass) {
245
330
  let newProps = Object.assign(Object.assign({}, props), { source: getSourceFromInputProps(props, shapeClass) });
@@ -341,11 +426,93 @@ function isValidQResult(of, query) {
341
426
  function isValidSetQResult(qResults, query) {
342
427
  return qResults.every((qResult) => isValidQResult(qResult, query));
343
428
  }
344
- function createLoadingSpinner() {
345
- return react_1.default.createElement('div', {
429
+ /**
430
+ * Built-in loading element used when nothing higher in the resolution chain
431
+ * sets one. Renders an SVG ring; `stroke: currentColor` lets parent context
432
+ * tint it. Style via `.ld-loader` in `@_linked/css/loader.css`.
433
+ */
434
+ function createDefaultLoader() {
435
+ return react_1.default.createElement('svg', {
346
436
  className: 'ld-loader',
347
437
  'aria-label': 'Loading',
348
438
  role: 'status',
349
- });
439
+ viewBox: '0 0 24 24',
440
+ xmlns: 'http://www.w3.org/2000/svg',
441
+ }, react_1.default.createElement('circle', {
442
+ className: 'ld-loader__track',
443
+ cx: 12,
444
+ cy: 12,
445
+ r: 9,
446
+ fill: 'none',
447
+ stroke: 'currentColor',
448
+ }), react_1.default.createElement('circle', {
449
+ className: 'ld-loader__arc',
450
+ cx: 12,
451
+ cy: 12,
452
+ r: 9,
453
+ fill: 'none',
454
+ stroke: 'currentColor',
455
+ }));
456
+ }
457
+ /**
458
+ * Built-in error element used when a query rejects and nothing higher in the
459
+ * resolution chain handles it. Renders a small cross SVG; styled by
460
+ * `.ld-error` in `@_linked/css/error.css`.
461
+ */
462
+ function createDefaultError() {
463
+ return react_1.default.createElement('svg', {
464
+ className: 'ld-error',
465
+ 'aria-label': 'Failed to load',
466
+ role: 'alert',
467
+ viewBox: '0 0 24 24',
468
+ xmlns: 'http://www.w3.org/2000/svg',
469
+ }, react_1.default.createElement('line', {
470
+ x1: 6,
471
+ y1: 6,
472
+ x2: 18,
473
+ y2: 18,
474
+ stroke: 'currentColor',
475
+ }), react_1.default.createElement('line', {
476
+ x1: 18,
477
+ y1: 6,
478
+ x2: 6,
479
+ y2: 18,
480
+ stroke: 'currentColor',
481
+ }));
482
+ }
483
+ function resolveLoader(instanceLoader, definitionLoader) {
484
+ var _a, _b;
485
+ return ((_b = (_a = instanceLoader !== null && instanceLoader !== void 0 ? instanceLoader : definitionLoader) !== null && _a !== void 0 ? _a : exports.LinkedComponentDefaults.loader) !== null && _b !== void 0 ? _b : createDefaultLoader());
486
+ }
487
+ /**
488
+ * Resolves the error element. Returns either a React element to render, or
489
+ * the literal `'rethrow'` — callers must rethrow the captured error when
490
+ * they receive the sentinel.
491
+ */
492
+ function resolveErrorElement(instanceErrorElement, definitionErrorElement) {
493
+ var _a, _b;
494
+ return ((_b = (_a = instanceErrorElement !== null && instanceErrorElement !== void 0 ? instanceErrorElement : definitionErrorElement) !== null && _a !== void 0 ? _a : exports.LinkedComponentDefaults.errorElement) !== null && _b !== void 0 ? _b : createDefaultError());
495
+ }
496
+ /**
497
+ * Normalizes the three factory signatures into a single shape:
498
+ * (query, fn) -> { query, component: fn, options: {} }
499
+ * (query, fn, options) -> { query, component: fn, options }
500
+ * ({ query, component, ... }) -> { query, component, options: { loader, errorElement } }
501
+ */
502
+ function normalizeFactoryArgs(arg1, arg2, arg3) {
503
+ if (arg2 === undefined &&
504
+ arg1 &&
505
+ typeof arg1 === 'object' &&
506
+ 'component' in arg1 &&
507
+ 'query' in arg1) {
508
+ const config = arg1;
509
+ const { query, component } = config, options = __rest(config, ["query", "component"]);
510
+ return { query, component, options };
511
+ }
512
+ return {
513
+ query: arg1,
514
+ component: arg2,
515
+ options: arg3 !== null && arg3 !== void 0 ? arg3 : {},
516
+ };
350
517
  }
351
518
  //# sourceMappingURL=LinkedComponent.js.map