@levo-so/site-runtime 0.3.22 → 0.3.23
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 +23 -0
- package/index.d.ts +56 -1
- package/index.js +414 -367
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# @levo-so/site-runtime
|
|
2
2
|
|
|
3
|
+
## 0.3.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Two records in one URL segment. `levoParams(key, pattern, [siblings])` declares how a route's single param splits into several record variables, e.g. `/health-packages/<package>-in-<city>`:
|
|
8
|
+
|
|
9
|
+
- `const split = levoParams("packages_in_cities", "{$packages}-in-{$cities}")` goes on the route as `params: split`; the page reads `packages` and `cities` from `Route.useParams()`.
|
|
10
|
+
- The segment splits on its rightmost separator. A segment that does not fit is declined, so a plain sibling page (`$packages.tsx`) keeps serving `/health-packages/<package>`.
|
|
11
|
+
- `split.link(values)` is the `params` of a `<Link>` to the page (TanStack types it from every parsed param, so the segment alone does not compile); `split.segment(values)` is the string form.
|
|
12
|
+
- A plain variable beside the split in the same route is named in the third argument: `levoParams("c_in_d", "{$c}-in-{$d}", ["a"])`.
|
|
13
|
+
- Both arguments must be string literals, or top-level consts holding them: the platform reads the declaration out of the route file to enumerate the page's sitemap URLs and pairs each variable with the record binding whose `param` names it.
|
|
14
|
+
|
|
15
|
+
Loud failures for URL and binding mismatches:
|
|
16
|
+
|
|
17
|
+
- A record binding whose `param` names no param of the route throws on staging previews with the route's params listed, and logs on production sites while the record resolves to null as before.
|
|
18
|
+
- A `levoParams` key the route does not have is declined and reported once in the server log; the type check and the platform's publish check refuse it.
|
|
19
|
+
- Pattern errors (no variable, duplicate name, two variables with nothing between them, stray braces) throw when the route module initialises.
|
|
20
|
+
|
|
21
|
+
Requires the matching platform release for sitemap enumeration and publish validation; sites must pin this version for the builder AI to use the feature.
|
|
22
|
+
|
|
23
|
+
- @levo-so/core@0.3.23
|
|
24
|
+
- @levo-so/insights@0.3.23
|
|
25
|
+
|
|
3
26
|
## 0.3.22
|
|
4
27
|
|
|
5
28
|
### Internal
|
package/index.d.ts
CHANGED
|
@@ -883,6 +883,51 @@ export declare interface ILevoOtpSlot {
|
|
|
883
883
|
};
|
|
884
884
|
}
|
|
885
885
|
|
|
886
|
+
/**
|
|
887
|
+
* One split segment, declared once: the route's `params` option IS this object, and every
|
|
888
|
+
* link to the route reuses the same const, so the pattern is never spelled twice.
|
|
889
|
+
* `TSiblings` names the route's other required params, `never` when the segment is the only
|
|
890
|
+
* one (see `levoParams`).
|
|
891
|
+
*/
|
|
892
|
+
export declare interface ILevoParams<TSegment extends string, TPattern extends string, TSiblings extends string = never> {
|
|
893
|
+
/**
|
|
894
|
+
* TanStack's `params.parse`: the variables split out of the segment beside the raw key and
|
|
895
|
+
* the siblings, or `false` for a segment the pattern does not fit, which declines the route
|
|
896
|
+
* so the sibling route with no pattern serves the URL. Throws when the key is not a param of
|
|
897
|
+
* the route at all (the first argument misspells the file's `$param`): see `parse` below.
|
|
898
|
+
*/
|
|
899
|
+
parse: (raw: Record<TSegment | NoInfer<TSiblings>, string>) => ILevoParsedParams<TSegment, TPattern, TSiblings> | false;
|
|
900
|
+
/**
|
|
901
|
+
* The segment the values compose (`"full-body-in-mumbai"`), for a string href: a JSON-LD
|
|
902
|
+
* url, a sitemap-style index. A missing or empty value throws: a link with a hole is a bug,
|
|
903
|
+
* not a URL.
|
|
904
|
+
*/
|
|
905
|
+
segment: (values: Record<ILevoPatternVars<TPattern>, string>) => string;
|
|
906
|
+
/**
|
|
907
|
+
* The `params` of a `<Link>` to the route: the values plus the composed segment under the
|
|
908
|
+
* raw key, with the sibling values passed through so a `<Link to="/$a/$c_in_d">` gets `a`
|
|
909
|
+
* beside the segment. Exists because TanStack types `Link params` from the route's PARSED
|
|
910
|
+
* params, so the variables are required beside the segment and the segment alone does not
|
|
911
|
+
* compile. Throws for a missing or empty value, as `segment` does.
|
|
912
|
+
*/
|
|
913
|
+
link: (values: Record<ILevoPatternVars<TPattern> | TSiblings, string>) => ILevoParsedParams<TSegment, TPattern, TSiblings>;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
/**
|
|
917
|
+
* What `parse` returns and `link` composes: the route's raw segment param (TanStack's
|
|
918
|
+
* parsed-params type must keep it), the route's other required params named as siblings
|
|
919
|
+
* (TanStack types the route's params from this alone, so a sibling not named here drops out
|
|
920
|
+
* of the route's types), plus one string per pattern variable.
|
|
921
|
+
*/
|
|
922
|
+
export declare type ILevoParsedParams<TSegment extends string, TPattern extends string, TSiblings extends string = never> = Record<TSegment | TSiblings, string> & Record<ILevoPatternVars<TPattern>, string>;
|
|
923
|
+
|
|
924
|
+
/**
|
|
925
|
+
* The variable names of a pattern as a union of literals:
|
|
926
|
+
* `ILevoPatternVars<"{$packages}-in-{$cities}">` is `"packages" | "cities"`.
|
|
927
|
+
* A pattern that is not a literal has no inferable names (`never`).
|
|
928
|
+
*/
|
|
929
|
+
export declare type ILevoPatternVars<TPattern extends string> = TPattern extends `${string}{$${infer TName}}${infer TRest}` ? TName | ILevoPatternVars<TRest> : never;
|
|
930
|
+
|
|
886
931
|
export declare interface ILevoPopupsProps {
|
|
887
932
|
/**
|
|
888
933
|
* The site's id (`site.json` `id`) — scopes the active-popups fetch. Absent → the
|
|
@@ -921,7 +966,9 @@ export declare interface ILevoRecordConfig {
|
|
|
921
966
|
* Route param this binding's slug comes from — `"slug"` on `/blog/$slug`, `"events"` on
|
|
922
967
|
* `/legal-events/$events`. Every generated record binding carries it: it is the mapping a
|
|
923
968
|
* multi-param route needs, since with two variable segments nothing else in the file says
|
|
924
|
-
* which binding fills which slot.
|
|
969
|
+
* which binding fills which slot. On a `levoParams` page it names one pattern variable
|
|
970
|
+
* (`"packages"` for `{$packages}-in-{$cities}`), which is how the platform pairs each variable
|
|
971
|
+
* with a collection. Round-tripped through the editor binding like the rest.
|
|
925
972
|
*
|
|
926
973
|
* Optional only for the pages written before it existed — see {@link recordSlug}.
|
|
927
974
|
*/
|
|
@@ -1755,6 +1802,8 @@ export declare const LevoEventRegister: ({ eventID, title, external, buttonText,
|
|
|
1755
1802
|
*/
|
|
1756
1803
|
export declare const LevoForm: React.FC<ILevoFormProps>;
|
|
1757
1804
|
|
|
1805
|
+
export declare const levoParams: <TSegment extends string, TPattern extends string, TSiblings extends string = never>(key: TSegment, pattern: TPattern, _siblings?: readonly TSiblings[]) => ILevoParams<TSegment, TPattern, TSiblings>;
|
|
1806
|
+
|
|
1758
1807
|
/**
|
|
1759
1808
|
* Mounts the site's popups, wired from `site.json`. Rendered once from the scaffold's
|
|
1760
1809
|
* `__root` (via the `SitePopups` shim), inside `<LevoSiteProvider>` — `PopupLoader` reads
|
|
@@ -1936,6 +1985,12 @@ export declare const parseRawHead: (raw: string) => IComposedHead;
|
|
|
1936
1985
|
* source resolves to null so it doesn't blank the whole page — the hook surfaces that
|
|
1937
1986
|
* binding's error while the rest render.
|
|
1938
1987
|
*
|
|
1988
|
+
* One failure is NOT absorbed outside production: a record binding whose `param` names no
|
|
1989
|
+
* param of the route. That is a wiring mistake in the page (never a transient fetch error),
|
|
1990
|
+
* it renders as a not-found record that no one can tell from a bad slug, and the preview is
|
|
1991
|
+
* where it gets fixed — so there the loader rejects with the message and the route's error
|
|
1992
|
+
* boundary shows it. See the branch below for what "preview" can mean here.
|
|
1993
|
+
*
|
|
1939
1994
|
* Returns the fetched values keyed by source key (records as the record object, lists as
|
|
1940
1995
|
* `{data, meta}`). The route loader returns this map, making it the route's `loaderData` —
|
|
1941
1996
|
* which `levoHead`'s dynamic config reads for per-record titles/descriptions/share images.
|