@chelone/core 0.6.0 → 0.9.0
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/assistant/assistant-session.d.ts +6 -0
- package/dist/assistant/assistant-session.js +204 -181
- package/dist/assistant/echo-transport.js +26 -29
- package/dist/assistant/http-transport.d.ts +10 -0
- package/dist/assistant/http-transport.js +98 -0
- package/dist/assistant/types.d.ts +1 -7
- package/dist/auth/access-control.d.ts +13 -5
- package/dist/auth/access-control.js +25 -21
- package/dist/auth/auth-options.d.ts +23 -17
- package/dist/auth/auth-options.js +82 -48
- package/dist/auth/permission-matrix.d.ts +12 -0
- package/dist/auth/permission-matrix.js +67 -0
- package/dist/auth/types.d.ts +14 -4
- package/dist/block-editor/block-document.d.ts +64 -0
- package/dist/block-editor/block-document.js +147 -0
- package/dist/block-editor/data-blocks.d.ts +63 -0
- package/dist/block-editor/data-blocks.js +117 -0
- package/dist/chart/chart-data.js +46 -44
- package/dist/command-menu/hotkey.js +58 -47
- package/dist/command-menu/recents.d.ts +4 -0
- package/dist/command-menu/recents.js +12 -11
- package/dist/command-menu/registry.d.ts +9 -5
- package/dist/command-menu/registry.js +36 -46
- package/dist/controller/calendar-dates.d.ts +12 -0
- package/dist/controller/calendar-dates.js +94 -113
- package/dist/controller/calendar-events.js +93 -88
- package/dist/controller/client-list-controller.d.ts +2 -2
- package/dist/controller/client-list-controller.js +251 -254
- package/dist/controller/data-table-columns.d.ts +2 -0
- package/dist/controller/data-table-columns.js +50 -56
- package/dist/controller/deep-equal.d.ts +1 -0
- package/dist/controller/deep-equal.js +14 -0
- package/dist/controller/filter-toggle.js +36 -44
- package/dist/controller/in-place-editor.d.ts +43 -0
- package/dist/controller/in-place-editor.js +43 -0
- package/dist/controller/infinite-list-controller.js +219 -189
- package/dist/controller/inspector.d.ts +55 -0
- package/dist/controller/inspector.js +70 -0
- package/dist/controller/job-monitor.d.ts +10 -4
- package/dist/controller/job-monitor.js +46 -47
- package/dist/controller/kanban-board.js +45 -24
- package/dist/controller/list-controller.d.ts +8 -5
- package/dist/controller/list-controller.js +447 -400
- package/dist/controller/list-params.js +96 -87
- package/dist/controller/pivot-grid.d.ts +4 -4
- package/dist/controller/pivot-grid.js +89 -95
- package/dist/controller/prev-next.d.ts +2 -2
- package/dist/controller/prev-next.js +74 -54
- package/dist/controller/record-controllers.d.ts +14 -6
- package/dist/controller/record-controllers.js +288 -257
- package/dist/controller/record-diff.d.ts +21 -0
- package/dist/controller/record-diff.js +50 -0
- package/dist/controller/record-timeline.d.ts +5 -5
- package/dist/controller/record-timeline.js +42 -30
- package/dist/controller/record-tree.js +57 -47
- package/dist/controller/record-workflow.d.ts +38 -16
- package/dist/controller/record-workflow.js +85 -64
- package/dist/controller/reference-many-controller.d.ts +2 -0
- package/dist/controller/reference-many-controller.js +199 -192
- package/dist/controller/reference-one-controller.d.ts +1 -1
- package/dist/controller/reference-one-controller.js +63 -56
- package/dist/controller/saved-queries.js +104 -91
- package/dist/controller/translate-fallback.js +10 -6
- package/dist/csv/export.d.ts +4 -3
- package/dist/csv/export.js +43 -40
- package/dist/csv/import-controller.d.ts +4 -0
- package/dist/csv/import-controller.js +189 -169
- package/dist/csv/match-headers.js +29 -22
- package/dist/csv/parse-with.js +60 -54
- package/dist/csv/run-import.js +69 -72
- package/dist/csv/validate-rows.d.ts +1 -1
- package/dist/csv/validate-rows.js +65 -52
- package/dist/data/cache-ops.d.ts +5 -4
- package/dist/data/cache-ops.js +208 -188
- package/dist/data/combine-data-providers.js +25 -23
- package/dist/data/data-provider-log.d.ts +45 -0
- package/dist/data/data-provider-log.js +93 -0
- package/dist/data/errors.js +14 -10
- package/dist/data/fake-provider.d.ts +6 -3
- package/dist/data/fake-provider.js +135 -114
- package/dist/data/fetch-utils.js +61 -44
- package/dist/data/filter-branch.d.ts +5 -0
- package/dist/data/filter-branch.js +10 -0
- package/dist/data/get-many-aggregate.js +84 -76
- package/dist/data/http-error.js +17 -12
- package/dist/data/keys.js +50 -36
- package/dist/data/mutation-options.d.ts +14 -9
- package/dist/data/mutation-options.js +93 -109
- package/dist/data/query-options.js +73 -68
- package/dist/data/remove-empty.d.ts +3 -0
- package/dist/data/remove-empty.js +11 -0
- package/dist/data/undoable.d.ts +2 -2
- package/dist/data/undoable.js +190 -174
- package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
- package/dist/data/with-lifecycle-callbacks.js +66 -52
- package/dist/environment/application-update-store.js +58 -55
- package/dist/environment/offline-store.js +21 -21
- package/dist/form/array-binding.d.ts +30 -11
- package/dist/form/array-binding.js +184 -166
- package/dist/form/choice-ids.d.ts +7 -0
- package/dist/form/choice-ids.js +11 -0
- package/dist/form/choices-controller.d.ts +22 -2
- package/dist/form/choices-controller.js +315 -275
- package/dist/form/date-format.d.ts +38 -0
- package/dist/form/date-format.js +89 -0
- package/dist/form/dirty-values.d.ts +2 -2
- package/dist/form/dirty-values.js +22 -11
- package/dist/form/duration.d.ts +22 -0
- package/dist/form/duration.js +49 -0
- package/dist/form/edit-create-form.d.ts +12 -5
- package/dist/form/edit-create-form.js +243 -188
- package/dist/form/event-value.d.ts +6 -0
- package/dist/form/event-value.js +17 -0
- package/dist/form/field-error.d.ts +14 -0
- package/dist/form/field-error.js +28 -0
- package/dist/form/field-name.d.ts +20 -0
- package/dist/form/field-name.js +6 -0
- package/dist/form/filter-form-values.js +63 -49
- package/dist/form/form-controller.d.ts +9 -1
- package/dist/form/form-controller.js +165 -160
- package/dist/form/form-groups.d.ts +4 -3
- package/dist/form/form-groups.js +79 -79
- package/dist/form/form-handle.d.ts +175 -0
- package/dist/form/form-handle.js +68 -0
- package/dist/form/input-binding.d.ts +56 -31
- package/dist/form/input-binding.js +171 -118
- package/dist/form/input-values.d.ts +140 -0
- package/dist/form/input-values.js +206 -0
- package/dist/form/json-text.d.ts +11 -0
- package/dist/form/json-text.js +62 -37
- package/dist/form/save-pipeline.d.ts +6 -8
- package/dist/form/save-pipeline.js +91 -82
- package/dist/form/set-form-values.d.ts +6 -0
- package/dist/form/set-form-values.js +10 -0
- package/dist/form/source.js +97 -65
- package/dist/form/text-of.d.ts +2 -0
- package/dist/form/text-of.js +7 -0
- package/dist/form/validators.d.ts +58 -19
- package/dist/form/validators.js +97 -71
- package/dist/geo/bbox.d.ts +5 -4
- package/dist/geo/bbox.js +69 -48
- package/dist/geo/bounds.d.ts +14 -3
- package/dist/geo/bounds.js +98 -68
- package/dist/geo/constraints.js +88 -93
- package/dist/geo/coordinates.d.ts +10 -0
- package/dist/geo/coordinates.js +44 -23
- package/dist/geo/editor.d.ts +13 -13
- package/dist/geo/editor.js +176 -153
- package/dist/geo/geocoding.d.ts +4 -4
- package/dist/geo/geocoding.js +38 -41
- package/dist/geo/geojson.d.ts +12 -74
- package/dist/geo/geojson.js +52 -40
- package/dist/geo/geometry-math.d.ts +4 -4
- package/dist/geo/geometry-math.js +100 -93
- package/dist/geo/index.d.ts +9 -8
- package/dist/geo/map-layers.d.ts +42 -7
- package/dist/geo/map-layers.js +88 -62
- package/dist/geo/map-style.d.ts +12 -0
- package/dist/geo/map-style.js +43 -32
- package/dist/geo/messages.js +48 -45
- package/dist/geo/nominatim.js +88 -80
- package/dist/geo/osm-presets.d.ts +4 -3
- package/dist/geo/osm-presets.js +108 -86
- package/dist/geo/osm-tags.js +14 -12
- package/dist/geo/overpass.d.ts +14 -2
- package/dist/geo/overpass.js +83 -90
- package/dist/geo/shape-value.d.ts +9 -5
- package/dist/geo/shape-value.js +169 -146
- package/dist/geo/snap-to-roads.d.ts +3 -3
- package/dist/geo/snap-to-roads.js +55 -50
- package/dist/geo/throttle.js +36 -39
- package/dist/guards.d.ts +44 -0
- package/dist/guards.js +77 -0
- package/dist/i18n/default-messages.js +34 -29
- package/dist/i18n/english-messages.d.ts +172 -0
- package/dist/i18n/english-messages.js +359 -189
- package/dist/i18n/i18n.d.ts +2 -2
- package/dist/i18n/i18n.js +47 -60
- package/dist/i18n/inflection.d.ts +34 -0
- package/dist/i18n/inflection.js +82 -0
- package/dist/i18n/messages.d.ts +10 -2
- package/dist/i18n/messages.js +17 -4
- package/dist/i18n/missing-keys.d.ts +4 -0
- package/dist/i18n/missing-keys.js +70 -62
- package/dist/i18n/translatable.d.ts +16 -1
- package/dist/i18n/translatable.js +40 -47
- package/dist/index.d.ts +87 -39
- package/dist/index.js +54 -301
- package/dist/json/deep-equal.d.ts +8 -0
- package/dist/json/deep-equal.js +24 -0
- package/dist/json/strip-json-comments.js +38 -42
- package/dist/noop.d.ts +2 -0
- package/dist/noop.js +4 -0
- package/dist/notification/error-message.d.ts +2 -0
- package/dist/notification/error-message.js +10 -0
- package/dist/notification/notification-store.d.ts +3 -2
- package/dist/notification/notification-store.js +41 -45
- package/dist/onboarding-tour/placement.d.ts +2 -0
- package/dist/onboarding-tour/placement.js +65 -78
- package/dist/onboarding-tour/tour-controller.js +46 -54
- package/dist/realtime/add-events-for-mutations.js +75 -81
- package/dist/realtime/announce-lock.js +16 -13
- package/dist/realtime/broadcast-channel-transport.js +65 -59
- package/dist/realtime/copy-members.js +22 -14
- package/dist/realtime/in-memory-lock-provider.js +40 -48
- package/dist/realtime/live.js +95 -101
- package/dist/realtime/lock-options.js +16 -16
- package/dist/realtime/lock-session.js +91 -78
- package/dist/realtime/memory-transport.js +25 -25
- package/dist/realtime/presence.js +120 -122
- package/dist/realtime/realtime-data-provider.d.ts +10 -0
- package/dist/realtime/realtime-data-provider.js +45 -42
- package/dist/realtime/reconnect-backoff.js +17 -0
- package/dist/realtime/sse-transport.d.ts +31 -0
- package/dist/realtime/sse-transport.js +235 -0
- package/dist/realtime/status-store.js +23 -28
- package/dist/realtime/topic-hub.js +62 -71
- package/dist/realtime/topics.js +10 -12
- package/dist/realtime/types.js +10 -12
- package/dist/realtime/unread-count.js +21 -21
- package/dist/realtime/websocket-transport.d.ts +32 -0
- package/dist/realtime/websocket-transport.js +306 -0
- package/dist/resource/describe-resource.d.ts +2 -0
- package/dist/resource/describe-resource.js +247 -219
- package/dist/resource/get-at-path.js +29 -14
- package/dist/resource/identifier.d.ts +18 -0
- package/dist/resource/identifier.js +27 -0
- package/dist/resource/record.d.ts +4 -0
- package/dist/resource/record.js +10 -0
- package/dist/resource/register.d.ts +7 -0
- package/dist/resource/registry-store.d.ts +45 -15
- package/dist/resource/registry-store.js +67 -60
- package/dist/resource/registry.d.ts +10 -0
- package/dist/resource/registry.js +8 -4
- package/dist/resource/source-path.d.ts +23 -2
- package/dist/rich-text/rich-text-extras.d.ts +134 -0
- package/dist/rich-text/rich-text-extras.js +181 -0
- package/dist/rich-text/rich-text-image.d.ts +124 -0
- package/dist/rich-text/rich-text-image.js +163 -0
- package/dist/rich-text/rich-text.d.ts +6 -0
- package/dist/rich-text/rich-text.js +125 -88
- package/dist/router/location.d.ts +24 -4
- package/dist/router/location.js +43 -18
- package/dist/router/match.js +47 -39
- package/dist/router/paths.js +40 -34
- package/dist/router/record-from-location.d.ts +1 -1
- package/dist/router/record-from-location.js +25 -17
- package/dist/store/adapters.js +51 -55
- package/dist/store/micro-store.js +57 -59
- package/dist/store/shallow-equal.d.ts +12 -0
- package/dist/store/shallow-equal.js +20 -0
- package/dist/store/store.js +54 -57
- package/dist/ui-defaults.d.ts +15 -0
- package/dist/ui-defaults.js +17 -0
- package/package.json +13 -11
package/dist/router/match.js
CHANGED
|
@@ -1,45 +1,53 @@
|
|
|
1
|
+
// src/router/match.ts
|
|
2
|
+
/** Compile a pattern into a case-insensitive regex + ordered param names. */
|
|
1
3
|
function compilePattern(pattern) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
4
|
+
const paramNames = [];
|
|
5
|
+
let regexpSource = `^${pattern.replace(/[\\.*+^${}|()[\]]/g, "\\$&").replace(/\\\*/g, "*").replace(/^\/*/, "/").replace(/\/+$/, "").replace(/\/:(\w+)/g, (_m, name) => {
|
|
6
|
+
paramNames.push(name);
|
|
7
|
+
return "/([^\\/]+)";
|
|
8
|
+
})}`;
|
|
9
|
+
if (pattern.endsWith("*")) {
|
|
10
|
+
paramNames.push("*");
|
|
11
|
+
regexpSource += pattern === "*" || pattern === "/*" ? "(.*)$" : "(?:\\/(.+)|\\/*)$";
|
|
12
|
+
} else regexpSource += "\\/*$";
|
|
13
|
+
return {
|
|
14
|
+
matcher: new RegExp(regexpSource, "i"),
|
|
15
|
+
paramNames
|
|
16
|
+
};
|
|
14
17
|
}
|
|
18
|
+
/** Safe URI-decode: fall back to the raw value on a malformed sequence. */
|
|
15
19
|
function safeDecode(value) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
try {
|
|
21
|
+
return decodeURIComponent(value);
|
|
22
|
+
} catch {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
21
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Match `pathname` against `pattern`. Returns the captured params, the matched
|
|
28
|
+
* `pathname`, and `pathnameBase` (the match minus any splat remainder), or
|
|
29
|
+
* `null` when the pattern does not match.
|
|
30
|
+
*/
|
|
22
31
|
function matchPath(pattern, pathname) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
const { matcher, paramNames } = compilePattern(pattern);
|
|
33
|
+
const match = pathname.match(matcher);
|
|
34
|
+
if (!match) return null;
|
|
35
|
+
const matchedPathname = match[0];
|
|
36
|
+
const hasSplat = paramNames[paramNames.length - 1] === "*";
|
|
37
|
+
let pathnameBase = matchedPathname;
|
|
38
|
+
const params = {};
|
|
39
|
+
paramNames.forEach((name, index) => {
|
|
40
|
+
if (name === "*") {
|
|
41
|
+
const splat = match[index + 1] ?? "";
|
|
42
|
+
pathnameBase = matchedPathname.slice(0, matchedPathname.length - splat.length).replace(/(.)\/+$/, "$1");
|
|
43
|
+
params["*"] = splat;
|
|
44
|
+
} else params[name] = safeDecode(match[index + 1] ?? "");
|
|
45
|
+
});
|
|
46
|
+
if (hasSplat && pathnameBase === "") pathnameBase = "/";
|
|
47
|
+
return {
|
|
48
|
+
params,
|
|
49
|
+
pathname: (matchedPathname.length > 1 ? matchedPathname.replace(/\/+$/, "") : matchedPathname) || "/",
|
|
50
|
+
pathnameBase
|
|
51
|
+
};
|
|
42
52
|
}
|
|
43
|
-
export {
|
|
44
|
-
matchPath
|
|
45
|
-
};
|
|
53
|
+
export { matchPath };
|
package/dist/router/paths.js
CHANGED
|
@@ -1,40 +1,46 @@
|
|
|
1
|
+
// src/router/paths.ts
|
|
2
|
+
/**
|
|
3
|
+
* Collapse runs of `/` into a single `/`, WITHOUT touching a `scheme://`
|
|
4
|
+
* authority separator. Matches ra-core's `removeDoubleSlashes` for internal
|
|
5
|
+
* paths while staying safe on the rare absolute URL.
|
|
6
|
+
*/
|
|
1
7
|
function removeDoubleSlashes(path) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
const schemeMatch = path.match(/^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//);
|
|
9
|
+
if (schemeMatch) {
|
|
10
|
+
const prefix = schemeMatch[0];
|
|
11
|
+
return prefix + path.slice(prefix.length).replace(/\/\/+/g, "/");
|
|
12
|
+
}
|
|
13
|
+
return path.replace(/\/\/+/g, "/");
|
|
8
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Prefix `path` with `basename`, collapsing the seam and any trailing basename
|
|
17
|
+
* slash. An empty basename is a no-op. The result is always slash-normalized.
|
|
18
|
+
*/
|
|
9
19
|
function joinBasename(path, basename = "") {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return collapsed.length > 1 ? collapsed.replace(/\/$/, "") : collapsed;
|
|
20
|
+
const collapsed = removeDoubleSlashes(basename ? `${basename}/${path}` : path);
|
|
21
|
+
return collapsed.length > 1 ? collapsed.replace(/\/$/, "") : collapsed;
|
|
13
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Build a route path for a link intent (parity §0a-11):
|
|
25
|
+
* `list`→`/res`, `create`→`/res/create`, `edit`→`/res/:id`, `show`→`/res/:id/show`.
|
|
26
|
+
* `id==null` on `edit`/`show` falls back to the list path. The id is
|
|
27
|
+
* `encodeURIComponent`d, and double slashes are removed from these four known
|
|
28
|
+
* intents. A custom string `type` is returned COMPLETELY verbatim — NO basename
|
|
29
|
+
* prefix, NO slash collapse — matching ra-core's `useCreatePath` `default`
|
|
30
|
+
* branch (the author owns the full, final path).
|
|
31
|
+
*/
|
|
14
32
|
function createPath(params, basename = "") {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return joinBasename(
|
|
28
|
-
`/${resource}/${encodeURIComponent(id)}/show`,
|
|
29
|
-
basename
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
default:
|
|
33
|
-
return type;
|
|
34
|
-
}
|
|
33
|
+
const { type, resource, id } = params;
|
|
34
|
+
switch (type) {
|
|
35
|
+
case "list": return joinBasename(`/${resource}`, basename);
|
|
36
|
+
case "create": return joinBasename(`/${resource}/create`, basename);
|
|
37
|
+
case "edit":
|
|
38
|
+
if (id == null) return joinBasename(`/${resource}`, basename);
|
|
39
|
+
return joinBasename(`/${resource}/${encodeURIComponent(id)}`, basename);
|
|
40
|
+
case "show":
|
|
41
|
+
if (id == null) return joinBasename(`/${resource}`, basename);
|
|
42
|
+
return joinBasename(`/${resource}/${encodeURIComponent(id)}/show`, basename);
|
|
43
|
+
default: return type;
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
|
-
export {
|
|
37
|
-
createPath,
|
|
38
|
-
joinBasename,
|
|
39
|
-
removeDoubleSlashes
|
|
40
|
-
};
|
|
46
|
+
export { createPath, joinBasename, removeDoubleSlashes };
|
|
@@ -13,6 +13,6 @@ export interface RecordFromLocationOptions {
|
|
|
13
13
|
/**
|
|
14
14
|
* The record at `state[stateSource]` if it is an object, else the JSON in the
|
|
15
15
|
* `searchSource` param. Returns `null` for no param, invalid JSON, a repeated
|
|
16
|
-
* param or a value that is not
|
|
16
|
+
* param or a value that is not an object. Never throws.
|
|
17
17
|
*/
|
|
18
18
|
export declare function getRecordFromLocation(location: Pick<CheloneLocation, "state" | "searchParams">, options?: RecordFromLocationOptions): Record<string, unknown> | null;
|
|
@@ -1,19 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { isRecord } from "../guards.js";
|
|
2
|
+
// src/router/record-from-location.ts
|
|
3
|
+
/**
|
|
4
|
+
* Read a seed record out of a location: the framework-free twin of ra-core's
|
|
5
|
+
* `useRecordFromLocation`. A router adapter passes its `CheloneLocation`;
|
|
6
|
+
* the clone link writes `?source=<json>`.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The record at `state[stateSource]` if it is an object, else the JSON in the
|
|
10
|
+
* `searchSource` param. Returns `null` for no param, invalid JSON, a repeated
|
|
11
|
+
* param or a value that is not an object. Never throws.
|
|
12
|
+
*/
|
|
4
13
|
function getRecordFromLocation(location, options = {}) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const { searchSource = "source", stateSource = "record" } = options;
|
|
15
|
+
const fromState = isRecord(location.state) ? location.state[stateSource] : void 0;
|
|
16
|
+
if (isRecord(fromState)) return fromState;
|
|
17
|
+
const values = location.searchParams.getAll(searchSource);
|
|
18
|
+
const [value] = values;
|
|
19
|
+
if (values.length !== 1 || value === void 0) return null;
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(value);
|
|
22
|
+
return isRecord(parsed) ? parsed : null;
|
|
23
|
+
} catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
16
26
|
}
|
|
17
|
-
export {
|
|
18
|
-
getRecordFromLocation
|
|
19
|
-
};
|
|
27
|
+
export { getRecordFromLocation };
|
package/dist/store/adapters.js
CHANGED
|
@@ -1,61 +1,57 @@
|
|
|
1
|
+
// src/store/adapters.ts
|
|
1
2
|
function memoryStoreAdapter(initial = {}) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
const map = new Map(Object.entries(initial));
|
|
4
|
+
return {
|
|
5
|
+
getItem: (key) => map.get(key),
|
|
6
|
+
setItem: (key, value) => void map.set(key, value),
|
|
7
|
+
removeItem: (key) => void map.delete(key)
|
|
8
|
+
};
|
|
8
9
|
}
|
|
10
|
+
/** window/localStorage touched ONLY inside method bodies — module import is SSR-safe. */
|
|
9
11
|
function storage() {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
if (typeof window === "undefined") return void 0;
|
|
13
|
+
try {
|
|
14
|
+
return window.localStorage;
|
|
15
|
+
} catch {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
function localStorageAdapter(options = {}) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return () => window.removeEventListener("storage", listener);
|
|
55
|
-
}
|
|
56
|
-
};
|
|
20
|
+
const prefix = options.prefix ?? "chelone.";
|
|
21
|
+
return {
|
|
22
|
+
getItem(key) {
|
|
23
|
+
const raw = storage()?.getItem(prefix + key);
|
|
24
|
+
if (raw == null) return void 0;
|
|
25
|
+
try {
|
|
26
|
+
return JSON.parse(raw);
|
|
27
|
+
} catch {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
setItem(key, value) {
|
|
32
|
+
try {
|
|
33
|
+
storage()?.setItem(prefix + key, JSON.stringify(value));
|
|
34
|
+
} catch {}
|
|
35
|
+
},
|
|
36
|
+
removeItem(key) {
|
|
37
|
+
storage()?.removeItem(prefix + key);
|
|
38
|
+
},
|
|
39
|
+
subscribeExternal(onChange) {
|
|
40
|
+
if (typeof window === "undefined") return () => {};
|
|
41
|
+
const listener = (event) => {
|
|
42
|
+
if (!event.key?.startsWith(prefix)) return;
|
|
43
|
+
const key = event.key.slice(prefix.length);
|
|
44
|
+
if (event.newValue == null) {
|
|
45
|
+
onChange(key, void 0);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
onChange(key, JSON.parse(event.newValue));
|
|
50
|
+
} catch {}
|
|
51
|
+
};
|
|
52
|
+
window.addEventListener("storage", listener);
|
|
53
|
+
return () => window.removeEventListener("storage", listener);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
57
56
|
}
|
|
58
|
-
export {
|
|
59
|
-
localStorageAdapter,
|
|
60
|
-
memoryStoreAdapter
|
|
61
|
-
};
|
|
57
|
+
export { localStorageAdapter, memoryStoreAdapter };
|
|
@@ -1,61 +1,59 @@
|
|
|
1
|
+
// src/store/micro-store.ts
|
|
1
2
|
function createMicroStore(initial, options) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
};
|
|
3
|
+
let state = initial;
|
|
4
|
+
let destroyed = false;
|
|
5
|
+
let attachTeardown;
|
|
6
|
+
const subscriptions = /* @__PURE__ */ new Set();
|
|
7
|
+
const cleanups = /* @__PURE__ */ new Set();
|
|
8
|
+
/** Runs the attach teardown at most once per attach cycle. */
|
|
9
|
+
const detach = () => {
|
|
10
|
+
const teardown = attachTeardown;
|
|
11
|
+
attachTeardown = void 0;
|
|
12
|
+
teardown?.();
|
|
13
|
+
};
|
|
14
|
+
return {
|
|
15
|
+
getSnapshot: () => state,
|
|
16
|
+
setState(update) {
|
|
17
|
+
if (destroyed) return;
|
|
18
|
+
const patch = typeof update === "function" ? update(state) : update;
|
|
19
|
+
let changed = false;
|
|
20
|
+
for (const key in patch) if (!Object.is(state[key], patch[key])) {
|
|
21
|
+
changed = true;
|
|
22
|
+
break;
|
|
23
|
+
}
|
|
24
|
+
if (!changed) return;
|
|
25
|
+
state = {
|
|
26
|
+
...state,
|
|
27
|
+
...patch
|
|
28
|
+
};
|
|
29
|
+
for (const subscription of subscriptions) subscription.callback();
|
|
30
|
+
},
|
|
31
|
+
subscribe(callback) {
|
|
32
|
+
if (destroyed) return () => {};
|
|
33
|
+
const subscription = { callback };
|
|
34
|
+
const isFirst = subscriptions.size === 0;
|
|
35
|
+
subscriptions.add(subscription);
|
|
36
|
+
if (isFirst && options?.onSubscribed) attachTeardown = options.onSubscribed() ?? void 0;
|
|
37
|
+
return () => {
|
|
38
|
+
if (!subscriptions.delete(subscription)) return;
|
|
39
|
+
if (subscriptions.size === 0 && !destroyed) detach();
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
destroy() {
|
|
43
|
+
if (destroyed) return;
|
|
44
|
+
destroyed = true;
|
|
45
|
+
detach();
|
|
46
|
+
for (const cleanup of cleanups) cleanup();
|
|
47
|
+
cleanups.clear();
|
|
48
|
+
subscriptions.clear();
|
|
49
|
+
},
|
|
50
|
+
onDestroy(cleanup) {
|
|
51
|
+
if (destroyed) {
|
|
52
|
+
cleanup();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
cleanups.add(cleanup);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
58
|
}
|
|
59
|
-
export {
|
|
60
|
-
createMicroStore
|
|
61
|
-
};
|
|
59
|
+
export { createMicroStore };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `shallowEqual(a, b)`: shallow equality with `Object.is` semantics at the top
|
|
3
|
+
* level. Parity with ra-core's `shallowEqual`.
|
|
4
|
+
*
|
|
5
|
+
* - `Object.is`-equal inputs are equal, so `NaN` equals `NaN` and `0` differs
|
|
6
|
+
* from `-0`;
|
|
7
|
+
* - two objects or arrays are equal iff they have the same own enumerable keys
|
|
8
|
+
* and each value pair is `Object.is`-equal; nested values compare by
|
|
9
|
+
* reference;
|
|
10
|
+
* - a non-object, or `null`, that is not `Object.is`-equal is unequal.
|
|
11
|
+
*/
|
|
12
|
+
export declare function shallowEqual(a: unknown, b: unknown): boolean;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/store/shallow-equal.ts
|
|
2
|
+
/**
|
|
3
|
+
* `shallowEqual(a, b)`: shallow equality with `Object.is` semantics at the top
|
|
4
|
+
* level. Parity with ra-core's `shallowEqual`.
|
|
5
|
+
*
|
|
6
|
+
* - `Object.is`-equal inputs are equal, so `NaN` equals `NaN` and `0` differs
|
|
7
|
+
* from `-0`;
|
|
8
|
+
* - two objects or arrays are equal iff they have the same own enumerable keys
|
|
9
|
+
* and each value pair is `Object.is`-equal; nested values compare by
|
|
10
|
+
* reference;
|
|
11
|
+
* - a non-object, or `null`, that is not `Object.is`-equal is unequal.
|
|
12
|
+
*/
|
|
13
|
+
function shallowEqual(a, b) {
|
|
14
|
+
if (Object.is(a, b)) return true;
|
|
15
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
16
|
+
const keysA = Object.keys(a);
|
|
17
|
+
if (keysA.length !== Object.keys(b).length) return false;
|
|
18
|
+
return keysA.every((key) => Object.hasOwn(b, key) && Object.is(Reflect.get(a, key), Reflect.get(b, key)));
|
|
19
|
+
}
|
|
20
|
+
export { shallowEqual };
|
package/dist/store/store.js
CHANGED
|
@@ -1,59 +1,56 @@
|
|
|
1
|
+
// src/store/store.ts
|
|
1
2
|
function createStore(adapter) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
};
|
|
3
|
+
const cache = /* @__PURE__ */ new Map();
|
|
4
|
+
const hydrated = /* @__PURE__ */ new Set();
|
|
5
|
+
const subscribers = /* @__PURE__ */ new Map();
|
|
6
|
+
const notify = (key) => {
|
|
7
|
+
const set = subscribers.get(key);
|
|
8
|
+
if (set) for (const cb of set) cb();
|
|
9
|
+
};
|
|
10
|
+
const apply = (key, value) => {
|
|
11
|
+
hydrated.add(key);
|
|
12
|
+
if (value === void 0) cache.delete(key);
|
|
13
|
+
else cache.set(key, value);
|
|
14
|
+
notify(key);
|
|
15
|
+
};
|
|
16
|
+
adapter?.subscribeExternal?.((key, value) => apply(key, value));
|
|
17
|
+
return {
|
|
18
|
+
getItem(key) {
|
|
19
|
+
if (!hydrated.has(key) && adapter) {
|
|
20
|
+
hydrated.add(key);
|
|
21
|
+
const persisted = adapter.getItem(key);
|
|
22
|
+
if (persisted !== void 0) cache.set(key, persisted);
|
|
23
|
+
}
|
|
24
|
+
return cache.get(key);
|
|
25
|
+
},
|
|
26
|
+
setItem(key, value) {
|
|
27
|
+
hydrated.add(key);
|
|
28
|
+
if (Object.is(cache.get(key), value)) return;
|
|
29
|
+
cache.set(key, value);
|
|
30
|
+
adapter?.setItem(key, value);
|
|
31
|
+
notify(key);
|
|
32
|
+
},
|
|
33
|
+
removeItem(key) {
|
|
34
|
+
hydrated.add(key);
|
|
35
|
+
cache.delete(key);
|
|
36
|
+
adapter?.removeItem(key);
|
|
37
|
+
notify(key);
|
|
38
|
+
},
|
|
39
|
+
subscribe(key, callback) {
|
|
40
|
+
let set = subscribers.get(key);
|
|
41
|
+
if (!set) {
|
|
42
|
+
set = /* @__PURE__ */ new Set();
|
|
43
|
+
subscribers.set(key, set);
|
|
44
|
+
}
|
|
45
|
+
set.add(callback);
|
|
46
|
+
return () => {
|
|
47
|
+
set.delete(callback);
|
|
48
|
+
if (set.size === 0 && subscribers.get(key) === set) subscribers.delete(key);
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
keys() {
|
|
52
|
+
return [...cache.keys()];
|
|
53
|
+
}
|
|
54
|
+
};
|
|
56
55
|
}
|
|
57
|
-
export {
|
|
58
|
-
createStore
|
|
59
|
-
};
|
|
56
|
+
export { createStore };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Defaults both adapters' components share. They have no module of their own. */
|
|
2
|
+
/** Past this many columns the columns panel gets a search box. */
|
|
3
|
+
export declare const SEARCH_THRESHOLD = 5;
|
|
4
|
+
/** The longest params or result JSON the data provider devtools show for one call. */
|
|
5
|
+
export declare const DEVTOOLS_MAX_VALUE_LENGTH = 2000;
|
|
6
|
+
/** The store key the theme mode is persisted under when `storageKey` is not set. */
|
|
7
|
+
export declare const DEFAULT_THEME_STORAGE_KEY = "chelone-theme";
|
|
8
|
+
/** The DOM id of the app-bar title portal target. */
|
|
9
|
+
export declare const TITLE_PORTAL_ID = "chelone-title-portal";
|
|
10
|
+
/** How long an undoable notification stays before it commits, in milliseconds. */
|
|
11
|
+
export declare const UNDO_AUTO_HIDE_MS = 5000;
|
|
12
|
+
/** Max rows an export fetches when `maxResults` is not set. */
|
|
13
|
+
export declare const DEFAULT_EXPORT_MAX_RESULTS = 1000;
|
|
14
|
+
/** Viewports narrower than this, in pixels, count as mobile. */
|
|
15
|
+
export declare const MOBILE_BREAKPOINT = 768;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/ui-defaults.ts
|
|
2
|
+
/** Defaults both adapters' components share. They have no module of their own. */
|
|
3
|
+
/** Past this many columns the columns panel gets a search box. */
|
|
4
|
+
var SEARCH_THRESHOLD = 5;
|
|
5
|
+
/** The longest params or result JSON the data provider devtools show for one call. */
|
|
6
|
+
var DEVTOOLS_MAX_VALUE_LENGTH = 2e3;
|
|
7
|
+
/** The store key the theme mode is persisted under when `storageKey` is not set. */
|
|
8
|
+
var DEFAULT_THEME_STORAGE_KEY = "chelone-theme";
|
|
9
|
+
/** The DOM id of the app-bar title portal target. */
|
|
10
|
+
var TITLE_PORTAL_ID = "chelone-title-portal";
|
|
11
|
+
/** How long an undoable notification stays before it commits, in milliseconds. */
|
|
12
|
+
var UNDO_AUTO_HIDE_MS = 5e3;
|
|
13
|
+
/** Max rows an export fetches when `maxResults` is not set. */
|
|
14
|
+
var DEFAULT_EXPORT_MAX_RESULTS = 1e3;
|
|
15
|
+
/** Viewports narrower than this, in pixels, count as mobile. */
|
|
16
|
+
var MOBILE_BREAKPOINT = 768;
|
|
17
|
+
export { DEFAULT_EXPORT_MAX_RESULTS, DEFAULT_THEME_STORAGE_KEY, DEVTOOLS_MAX_VALUE_LENGTH, MOBILE_BREAKPOINT, SEARCH_THRESHOLD, TITLE_PORTAL_ID, UNDO_AUTO_HIDE_MS };
|