@chelone/core 0.4.0 → 0.6.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.
Files changed (38) hide show
  1. package/dist/assistant/assistant-session.d.ts +22 -0
  2. package/dist/assistant/assistant-session.js +185 -0
  3. package/dist/assistant/echo-transport.d.ts +7 -0
  4. package/dist/assistant/echo-transport.js +31 -0
  5. package/dist/assistant/types.d.ts +60 -0
  6. package/dist/chart/chart-data.d.ts +25 -0
  7. package/dist/chart/chart-data.js +59 -0
  8. package/dist/controller/infinite-list-controller.js +1 -1
  9. package/dist/controller/job-monitor.d.ts +42 -0
  10. package/dist/controller/job-monitor.js +59 -0
  11. package/dist/controller/pivot-grid.d.ts +36 -0
  12. package/dist/controller/pivot-grid.js +105 -0
  13. package/dist/controller/record-timeline.d.ts +35 -0
  14. package/dist/controller/record-timeline.js +36 -0
  15. package/dist/data/cache-ops.js +1 -3
  16. package/dist/form/edit-create-form.js +7 -7
  17. package/dist/i18n/i18n.d.ts +6 -0
  18. package/dist/i18n/i18n.js +13 -1
  19. package/dist/i18n/missing-keys.d.ts +19 -0
  20. package/dist/i18n/missing-keys.js +64 -0
  21. package/dist/index.d.ts +27 -0
  22. package/dist/index.js +43 -0
  23. package/dist/onboarding-tour/placement.d.ts +34 -0
  24. package/dist/onboarding-tour/placement.js +82 -0
  25. package/dist/onboarding-tour/tour-controller.d.ts +25 -0
  26. package/dist/onboarding-tour/tour-controller.js +58 -0
  27. package/dist/realtime/announce-lock.d.ts +7 -0
  28. package/dist/realtime/announce-lock.js +15 -0
  29. package/dist/realtime/broadcast-channel-transport.d.ts +14 -0
  30. package/dist/realtime/broadcast-channel-transport.js +63 -0
  31. package/dist/realtime/in-memory-lock-provider.js +3 -14
  32. package/dist/realtime/memory-transport.js +10 -51
  33. package/dist/realtime/reconnect-backoff.d.ts +15 -0
  34. package/dist/realtime/topic-hub.d.ts +24 -0
  35. package/dist/realtime/topic-hub.js +75 -0
  36. package/dist/rich-text/rich-text.d.ts +56 -0
  37. package/dist/rich-text/rich-text.js +105 -0
  38. package/package.json +3 -3
@@ -0,0 +1,36 @@
1
+ import { getAtPath } from "../resource/get-at-path.js";
2
+ import { parseCalendarDate } from "./calendar-dates.js";
3
+ function toTimelineEntries(records, options) {
4
+ const { messageSource, timestampSource, userSource, iconSource } = options;
5
+ return records.map((record) => {
6
+ const message = getAtPath(record, messageSource);
7
+ const user = userSource === void 0 ? void 0 : getAtPath(record, userSource);
8
+ const icon = iconSource === void 0 ? void 0 : getAtPath(record, iconSource);
9
+ return {
10
+ id: record.id,
11
+ record,
12
+ message: message == null ? "" : String(message),
13
+ date: parseCalendarDate(getAtPath(record, timestampSource)),
14
+ user: user == null || user === "" ? void 0 : String(user),
15
+ icon: icon == null || icon === "" ? void 0 : String(icon)
16
+ };
17
+ });
18
+ }
19
+ const MINUTE = 60;
20
+ const HOUR = 3600;
21
+ const DAY = 86400;
22
+ const MONTH = DAY * 30;
23
+ function formatRelativeTime(date, now, locale) {
24
+ const delta = (date.getTime() - now.getTime()) / 1e3;
25
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: "auto" });
26
+ const distance = Math.abs(delta);
27
+ if (distance < MINUTE) return rtf.format(Math.round(delta), "second");
28
+ if (distance < HOUR) return rtf.format(Math.round(delta / MINUTE), "minute");
29
+ if (distance < DAY) return rtf.format(Math.round(delta / HOUR), "hour");
30
+ if (distance < MONTH) return rtf.format(Math.round(delta / DAY), "day");
31
+ return rtf.format(Math.round(delta / MONTH), "month");
32
+ }
33
+ export {
34
+ formatRelativeTime,
35
+ toTimelineEntries
36
+ };
@@ -6,9 +6,7 @@ function singleResultListKeyPrefixes(resource) {
6
6
  ];
7
7
  }
8
8
  function withoutIds(page, idSet) {
9
- const kept = page.data.filter(
10
- (record) => !idSet.has(String(record.id))
11
- );
9
+ const kept = page.data.filter((record) => !idSet.has(String(record.id)));
12
10
  return kept.length === page.data.length ? void 0 : { ...page, data: kept };
13
11
  }
14
12
  function withPatchedRows(page, idSet, data) {
@@ -132,17 +132,17 @@ function createEditFormController(ctx, resource, options) {
132
132
  return;
133
133
  }
134
134
  if (action === "partial-apply") {
135
- const pathAccess = form;
136
- const fieldMeta = form.state.fieldMeta;
137
135
  const dirtyValues = [];
138
- for (const [path, meta] of Object.entries(fieldMeta)) {
139
- if (meta.isDirty) {
140
- dirtyValues.push([path, pathAccess.getFieldValue(path)]);
141
- }
136
+ for (const [path, meta] of Object.entries(
137
+ form.state.fieldMeta
138
+ )) {
139
+ if (!meta?.isDirty) continue;
140
+ const name = path;
141
+ dirtyValues.push([name, form.getFieldValue(name)]);
142
142
  }
143
143
  form.reset(merged);
144
144
  for (const [path, value] of dirtyValues) {
145
- pathAccess.setFieldValue(path, value, { dontRunListeners: true });
145
+ form.setFieldValue(path, value, { dontRunListeners: true });
146
146
  }
147
147
  return;
148
148
  }
@@ -38,5 +38,11 @@ export declare function createI18n<const TCatalog extends MessageCatalog>(option
38
38
  locale: string;
39
39
  messages: Record<string, TCatalog>;
40
40
  fallbackLocale?: string;
41
+ /**
42
+ * Called when the current locale's catalog holds no own entry for a key,
43
+ * even when `fallbackLocale` supplies the text. `fallback` is the string `_`
44
+ * param. A throwing callback goes to `console.error`; `translate` is unchanged.
45
+ */
46
+ onMissingKey?: (key: string, locale: string, fallback: string | undefined) => void;
41
47
  }): CheloneI18n<TCatalog>;
42
48
  export {};
package/dist/i18n/i18n.js CHANGED
@@ -26,7 +26,19 @@ function createI18n(options) {
26
26
  return {
27
27
  translate(key, ...args) {
28
28
  const params = args[0];
29
- const value = lookup(options.messages[locale], key) ?? (options.fallbackLocale ? lookup(options.messages[options.fallbackLocale], key) : void 0);
29
+ const own = lookup(options.messages[locale], key);
30
+ if (own === void 0 && options.onMissingKey) {
31
+ try {
32
+ options.onMissingKey(
33
+ key,
34
+ locale,
35
+ typeof params?._ === "string" ? params._ : void 0
36
+ );
37
+ } catch (error) {
38
+ console.error(error);
39
+ }
40
+ }
41
+ const value = own ?? (options.fallbackLocale ? lookup(options.messages[options.fallbackLocale], key) : void 0);
30
42
  if (value === void 0) {
31
43
  if (typeof params?._ === "string") return interpolate(params._, params);
32
44
  return key;
@@ -0,0 +1,19 @@
1
+ export interface MissingKeyEntry {
2
+ key: string;
3
+ fallback: string | undefined;
4
+ translation: string;
5
+ }
6
+ export interface MissingKeyStore {
7
+ /** Has the `onMissingKey` signature: pass it as `onMissingKey: store.record`. */
8
+ record(key: string, locale: string, fallback: string | undefined): void;
9
+ /** The same array until that locale's entries change. */
10
+ getEntries(locale: string): readonly MissingKeyEntry[];
11
+ /** Ignores a key that was not recorded. */
12
+ setTranslation(locale: string, key: string, text: string): void;
13
+ clear(locale: string): void;
14
+ /** Flat `{ key: text }` JSON, two-space indented, non-blank translations only. */
15
+ toJson(locale: string): string;
16
+ /** Notified once per microtask, however many entries changed. */
17
+ subscribe(callback: () => void): () => void;
18
+ }
19
+ export declare function createMissingKeyStore(): MissingKeyStore;
@@ -0,0 +1,64 @@
1
+ const NO_ENTRIES = [];
2
+ function createMissingKeyStore() {
3
+ const byLocale = /* @__PURE__ */ new Map();
4
+ const snapshots = /* @__PURE__ */ new Map();
5
+ const subscribers = /* @__PURE__ */ new Set();
6
+ let scheduled = false;
7
+ const changed = (locale) => {
8
+ snapshots.delete(locale);
9
+ if (scheduled) return;
10
+ scheduled = true;
11
+ queueMicrotask(() => {
12
+ scheduled = false;
13
+ for (const cb of [...subscribers]) cb();
14
+ });
15
+ };
16
+ const getEntries = (locale) => {
17
+ const cached = snapshots.get(locale);
18
+ if (cached) return cached;
19
+ const entries = byLocale.get(locale);
20
+ if (!entries?.size) return NO_ENTRIES;
21
+ const snapshot = [...entries.values()];
22
+ snapshots.set(locale, snapshot);
23
+ return snapshot;
24
+ };
25
+ return {
26
+ record(key, locale, fallback) {
27
+ let entries = byLocale.get(locale);
28
+ if (!entries) {
29
+ entries = /* @__PURE__ */ new Map();
30
+ byLocale.set(locale, entries);
31
+ }
32
+ if (entries.has(key)) return;
33
+ entries.set(key, { key, fallback, translation: "" });
34
+ changed(locale);
35
+ },
36
+ getEntries,
37
+ setTranslation(locale, key, text) {
38
+ const entries = byLocale.get(locale);
39
+ const entry = entries?.get(key);
40
+ if (!entries || !entry || entry.translation === text) return;
41
+ entries.set(key, { ...entry, translation: text });
42
+ changed(locale);
43
+ },
44
+ clear(locale) {
45
+ if (!byLocale.get(locale)?.size) return;
46
+ byLocale.delete(locale);
47
+ changed(locale);
48
+ },
49
+ toJson(locale) {
50
+ const out = /* @__PURE__ */ new Map();
51
+ for (const { key, translation } of getEntries(locale)) {
52
+ if (translation.trim() !== "") out.set(key, translation);
53
+ }
54
+ return JSON.stringify(Object.fromEntries(out), null, 2);
55
+ },
56
+ subscribe(callback) {
57
+ subscribers.add(callback);
58
+ return () => void subscribers.delete(callback);
59
+ }
60
+ };
61
+ }
62
+ export {
63
+ createMissingKeyStore
64
+ };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,16 @@
1
1
  export { revalidateLogic } from "@tanstack/form-core";
2
+ export type { AssistantSession, AssistantSessionState, CreateAssistantSessionOptions, } from "./assistant/assistant-session.js";
3
+ export { createAssistantSession } from "./assistant/assistant-session.js";
4
+ export type { EchoAssistantTransportOptions } from "./assistant/echo-transport.js";
5
+ export { echoAssistantTransport } from "./assistant/echo-transport.js";
6
+ export type { AssistantChunk, AssistantMessage, AssistantTool, AssistantToolCall, AssistantToolDeclaration, AssistantTransport, JsonObject, JsonValue, } from "./assistant/types.js";
2
7
  export type { Permission } from "./auth/access-control.js";
3
8
  export { canAccessWithPermissions } from "./auth/access-control.js";
4
9
  export type { CheckErrorOutcome } from "./auth/auth-options.js";
5
10
  export { authStateQueryOptions, canAccessQueryOptions, checkError, identityQueryOptions, permissionsQueryOptions, } from "./auth/auth-options.js";
6
11
  export type { AuthProvider, CanAccessParams, UserIdentity } from "./auth/types.js";
12
+ export type { CartesianRow, DonutSlice, MetricDelta, } from "./chart/chart-data.js";
13
+ export { chartColor, DEFAULT_CHART_COLORS, getMetricDelta, hasChartValues, toCartesianRows, toDonutSlices, } from "./chart/chart-data.js";
7
14
  export type { HotkeyEvent, HotkeyTarget } from "./command-menu/hotkey.js";
8
15
  export { isTypingTarget, matchesHotkey, shouldHandleHotkey, } from "./command-menu/hotkey.js";
9
16
  export type { RecentEntry } from "./command-menu/recents.js";
@@ -21,16 +28,22 @@ export { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTab
21
28
  export { isFilterSelected, toggleFilterValue, } from "./controller/filter-toggle.js";
22
29
  export type { InfiniteListController, InfiniteListControllerState, } from "./controller/infinite-list-controller.js";
23
30
  export { createInfiniteListController } from "./controller/infinite-list-controller.js";
31
+ export type { JobActionOptions, JobActions, JobPlan, } from "./controller/job-monitor.js";
32
+ export { DEFAULT_JOB_TABS, getJobActions, planJobCancel, planJobRetry, } from "./controller/job-monitor.js";
24
33
  export type { KanbanBucket, KanbanColumnDef, KanbanMove, } from "./controller/kanban-board.js";
25
34
  export { buildKanbanBuckets, planKanbanMove, } from "./controller/kanban-board.js";
26
35
  export type { ListController, ListControllerContext, ListControllerOptions, ListControllerState, ListParamsPatch, } from "./controller/list-controller.js";
27
36
  export { createListController, listControllerActions, } from "./controller/list-controller.js";
28
37
  export type { ListParamsQuery, ListUrlState, } from "./controller/list-params.js";
29
38
  export { hasCustomParams, listPatchFromSearch, parseListParams, serializeListParams, serializeListState, } from "./controller/list-params.js";
39
+ export type { PivotAggregator, PivotOptions, PivotTable, } from "./controller/pivot-grid.js";
40
+ export { buildPivotTable, formatPivotValue, } from "./controller/pivot-grid.js";
30
41
  export type { PrevNextOptions, PrevNextPage, PrevNextParams, PrevNextResolution, PrevNextStoredParams, } from "./controller/prev-next.js";
31
42
  export { canUseCachedPage, getPrevNextParams, resolvePrevNext, } from "./controller/prev-next.js";
32
43
  export type { CreateController, CreateControllerOptions, CreateControllerState, DeleteController, DeleteControllerOptions, DeleteControllerState, DeleteOneOptions, EditController, EditControllerOptions, EditControllerState, RecordControllerContext, RedirectRequest, RedirectTarget, SaveOptions, SaveTransform, ShowController, ShowControllerOptions, ShowControllerState, } from "./controller/record-controllers.js";
33
44
  export { createCreateController, createDeleteController, createEditController, createShowController, } from "./controller/record-controllers.js";
45
+ export type { RecordTimelineEntry, ToTimelineEntriesOptions, } from "./controller/record-timeline.js";
46
+ export { formatRelativeTime, toTimelineEntries, } from "./controller/record-timeline.js";
34
47
  export type { RecordTreeNode } from "./controller/record-tree.js";
35
48
  export { buildRecordTree } from "./controller/record-tree.js";
36
49
  export type { AllowedTransitions, ApprovalOptions, ApprovalState, TransitionOptions, } from "./controller/record-workflow.js";
@@ -125,13 +138,22 @@ export type { AnyCheloneI18n, CheloneI18n } from "./i18n/i18n.js";
125
138
  export { createI18n } from "./i18n/i18n.js";
126
139
  export type { ExtractParams, MessageCatalog, MessageKey, MessageValue, PluralMessage, TranslateParams, } from "./i18n/messages.js";
127
140
  export { defineMessages } from "./i18n/messages.js";
141
+ export type { MissingKeyEntry, MissingKeyStore, } from "./i18n/missing-keys.js";
142
+ export { createMissingKeyStore } from "./i18n/missing-keys.js";
128
143
  export type { TranslatableController, TranslatableOptions, TranslatableState, } from "./i18n/translatable.js";
129
144
  export { createTranslatableController, getRecordForLocale, } from "./i18n/translatable.js";
130
145
  export { stripJsonComments } from "./json/strip-json-comments.js";
131
146
  export type { Notification, NotificationStore, NotifyOptions, } from "./notification/notification-store.js";
132
147
  export { createNotificationStore } from "./notification/notification-store.js";
148
+ export type { PlaceTourCardOptions, TourCardPosition, TourPlacement, TourRect, } from "./onboarding-tour/placement.js";
149
+ export { placeTourCard, tourSpotlightPath, } from "./onboarding-tour/placement.js";
150
+ export type { TourController, TourControllerOptions, TourEnd, TourState, } from "./onboarding-tour/tour-controller.js";
151
+ export { createTourController, onboardingTourKey, } from "./onboarding-tour/tour-controller.js";
133
152
  export type { AddEventsForMutationsOptions } from "./realtime/add-events-for-mutations.js";
134
153
  export { addEventsForMutations } from "./realtime/add-events-for-mutations.js";
154
+ export { announceLock } from "./realtime/announce-lock.js";
155
+ export type { BroadcastChannelTransport, BroadcastChannelTransportOptions, } from "./realtime/broadcast-channel-transport.js";
156
+ export { broadcastChannelTransport } from "./realtime/broadcast-channel-transport.js";
135
157
  export type { InMemoryLockProviderOptions } from "./realtime/in-memory-lock-provider.js";
136
158
  export { inMemoryLockProvider } from "./realtime/in-memory-lock-provider.js";
137
159
  export type { LiveOptions, LiveSubscription } from "./realtime/live.js";
@@ -144,8 +166,11 @@ export { memoryTransport } from "./realtime/memory-transport.js";
144
166
  export type { PresenceSession, PresenceSessionDataProvider, PresenceSessionOptions, PresenceSessionState, PresenceUser, } from "./realtime/presence.js";
145
167
  export { createPresenceSession, getPresenceInitials, toPresenceUser, } from "./realtime/presence.js";
146
168
  export { assertRealtimeDataProvider, isRealtimeDataProvider, realtimeDataProvider, } from "./realtime/realtime-data-provider.js";
169
+ export type { RealtimeReconnectConfig } from "./realtime/reconnect-backoff.js";
147
170
  export type { RealtimeStatusState } from "./realtime/status-store.js";
148
171
  export { createRealtimeStatusStore } from "./realtime/status-store.js";
172
+ export type { TopicHub } from "./realtime/topic-hub.js";
173
+ export { createTopicHub } from "./realtime/topic-hub.js";
149
174
  export { lockResourceTopic, lockTopic, presenceTopic, recordTopic, resourceTopic, } from "./realtime/topics.js";
150
175
  export type { GetLockParams, GetLocksParams, Lock, LockParams, LockProvider, RealtimeConnectionStatus, RealtimeDataProvider, RealtimeDataProviderOptions, RealtimeEvent, RealtimeEventType, RealtimeTransport, RealtimeTransportError, RealtimeTransportErrorKind, SubscriptionCallback, UnlockParams, } from "./realtime/types.js";
151
176
  export { LockConflictError } from "./realtime/types.js";
@@ -162,6 +187,8 @@ export { defineResources } from "./resource/registry.js";
162
187
  export type { ComputeDefinitionProps, ResourceDefinition, ResourceDefinitionMap, ResourceRegistry, ResourceRegistryListener, } from "./resource/registry-store.js";
163
188
  export { computeDefinition, createResourceRegistry, } from "./resource/registry-store.js";
164
189
  export type { AnySourcePath, AnySourcePathOf, FilterSourceKey, RowSourcePath, SourceKey, SourcePath, SourceProp, SourceValue, } from "./resource/source-path.js";
190
+ export type { IsSafeImageSrcOptions, RichTextBlockType, RichTextHeadingLevel, RichTextToolbarGroup, RichTextToolbarItem, RichTextToolbarItemId, } from "./rich-text/rich-text.js";
191
+ export { isSafeImageSrc, isSafeLinkUrl, richTextBlockTypes, richTextSanitizeOptions, richTextStarterKitOptions, richTextToolbarItems, } from "./rich-text/rich-text.js";
165
192
  export type { CheloneLocation, NavigateOpts } from "./router/location.js";
166
193
  export { parseLocation } from "./router/location.js";
167
194
  export type { PathMatch } from "./router/match.js";
package/dist/index.js CHANGED
@@ -1,6 +1,9 @@
1
1
  import { revalidateLogic } from "@tanstack/form-core";
2
+ import { createAssistantSession } from "./assistant/assistant-session.js";
3
+ import { echoAssistantTransport } from "./assistant/echo-transport.js";
2
4
  import { canAccessWithPermissions } from "./auth/access-control.js";
3
5
  import { authStateQueryOptions, canAccessQueryOptions, checkError, identityQueryOptions, permissionsQueryOptions } from "./auth/auth-options.js";
6
+ import { DEFAULT_CHART_COLORS, chartColor, getMetricDelta, hasChartValues, toCartesianRows, toDonutSlices } from "./chart/chart-data.js";
4
7
  import { isTypingTarget, matchesHotkey, shouldHandleHotkey } from "./command-menu/hotkey.js";
5
8
  import { recentsKey, rememberRecent } from "./command-menu/recents.js";
6
9
  import { createCommandRegistry, getVisibleCommands, groupCommands } from "./command-menu/registry.js";
@@ -10,11 +13,14 @@ import { createClientListController } from "./controller/client-list-controller.
10
13
  import { arrangeColumns, columnLabelMatches, dataTableColumnKeys, defaultDataTableStoreKey, getDataTableColumnId, moveColumn, toggleHiddenColumn } from "./controller/data-table-columns.js";
11
14
  import { isFilterSelected, toggleFilterValue } from "./controller/filter-toggle.js";
12
15
  import { createInfiniteListController } from "./controller/infinite-list-controller.js";
16
+ import { DEFAULT_JOB_TABS, getJobActions, planJobCancel, planJobRetry } from "./controller/job-monitor.js";
13
17
  import { buildKanbanBuckets, planKanbanMove } from "./controller/kanban-board.js";
14
18
  import { createListController, listControllerActions } from "./controller/list-controller.js";
15
19
  import { hasCustomParams, listPatchFromSearch, parseListParams, serializeListParams, serializeListState } from "./controller/list-params.js";
20
+ import { buildPivotTable, formatPivotValue } from "./controller/pivot-grid.js";
16
21
  import { canUseCachedPage, getPrevNextParams, resolvePrevNext } from "./controller/prev-next.js";
17
22
  import { createCreateController, createDeleteController, createEditController, createShowController } from "./controller/record-controllers.js";
23
+ import { formatRelativeTime, toTimelineEntries } from "./controller/record-timeline.js";
18
24
  import { buildRecordTree } from "./controller/record-tree.js";
19
25
  import { buildApprovalUpdate, getAllowedTransitions, getApprovalState } from "./controller/record-workflow.js";
20
26
  import { createReferenceManyController } from "./controller/reference-many-controller.js";
@@ -73,10 +79,15 @@ import { defaultMessages } from "./i18n/default-messages.js";
73
79
  import { englishMessages } from "./i18n/english-messages.js";
74
80
  import { createI18n } from "./i18n/i18n.js";
75
81
  import { defineMessages } from "./i18n/messages.js";
82
+ import { createMissingKeyStore } from "./i18n/missing-keys.js";
76
83
  import { createTranslatableController, getRecordForLocale } from "./i18n/translatable.js";
77
84
  import { stripJsonComments } from "./json/strip-json-comments.js";
78
85
  import { createNotificationStore } from "./notification/notification-store.js";
86
+ import { placeTourCard, tourSpotlightPath } from "./onboarding-tour/placement.js";
87
+ import { createTourController, onboardingTourKey } from "./onboarding-tour/tour-controller.js";
79
88
  import { addEventsForMutations } from "./realtime/add-events-for-mutations.js";
89
+ import { announceLock } from "./realtime/announce-lock.js";
90
+ import { broadcastChannelTransport } from "./realtime/broadcast-channel-transport.js";
80
91
  import { inMemoryLockProvider } from "./realtime/in-memory-lock-provider.js";
81
92
  import { subscribeLiveLock, subscribeLiveLocks, subscribeLiveRecord, subscribeLiveRecords, subscribeLiveResource } from "./realtime/live.js";
82
93
  import { getLockOptions, getLocksOptions } from "./realtime/lock-options.js";
@@ -85,6 +96,7 @@ import { memoryTransport } from "./realtime/memory-transport.js";
85
96
  import { createPresenceSession, getPresenceInitials, toPresenceUser } from "./realtime/presence.js";
86
97
  import { assertRealtimeDataProvider, isRealtimeDataProvider, realtimeDataProvider } from "./realtime/realtime-data-provider.js";
87
98
  import { createRealtimeStatusStore } from "./realtime/status-store.js";
99
+ import { createTopicHub } from "./realtime/topic-hub.js";
88
100
  import { lockResourceTopic, lockTopic, presenceTopic, recordTopic, resourceTopic } from "./realtime/topics.js";
89
101
  import { LockConflictError } from "./realtime/types.js";
90
102
  import { clearUnread, subscribeUnreadCount, unreadKey } from "./realtime/unread-count.js";
@@ -92,6 +104,7 @@ import { describeResource } from "./resource/describe-resource.js";
92
104
  import { getAtPath } from "./resource/get-at-path.js";
93
105
  import { defineResources } from "./resource/registry.js";
94
106
  import { computeDefinition, createResourceRegistry } from "./resource/registry-store.js";
107
+ import { isSafeImageSrc, isSafeLinkUrl, richTextBlockTypes, richTextSanitizeOptions, richTextStarterKitOptions, richTextToolbarItems } from "./rich-text/rich-text.js";
95
108
  import { parseLocation } from "./router/location.js";
96
109
  import { matchPath } from "./router/match.js";
97
110
  import { createPath, joinBasename, removeDoubleSlashes } from "./router/paths.js";
@@ -100,6 +113,8 @@ import { localStorageAdapter, memoryStoreAdapter } from "./store/adapters.js";
100
113
  import { createMicroStore } from "./store/micro-store.js";
101
114
  import { createStore } from "./store/store.js";
102
115
  export {
116
+ DEFAULT_CHART_COLORS,
117
+ DEFAULT_JOB_TABS,
103
118
  DEFAULT_SHAPE_STYLE,
104
119
  HttpError,
105
120
  LockConflictError,
@@ -109,6 +124,7 @@ export {
109
124
  OverpassTimeoutError,
110
125
  ValidationError,
111
126
  addEventsForMutations,
127
+ announceLock,
112
128
  applyCsvMapping,
113
129
  areaInTypeOf,
114
130
  arrangeColumns,
@@ -117,9 +133,11 @@ export {
117
133
  assertRealtimeDataProvider,
118
134
  authStateQueryOptions,
119
135
  bboxToPolygon,
136
+ broadcastChannelTransport,
120
137
  buildApprovalUpdate,
121
138
  buildKanbanBuckets,
122
139
  buildOverpassQuery,
140
+ buildPivotTable,
123
141
  buildRecordTree,
124
142
  calendarDayKey,
125
143
  calendarDays,
@@ -131,6 +149,7 @@ export {
131
149
  canAccessQueryOptions,
132
150
  canAccessWithPermissions,
133
151
  canUseCachedPage,
152
+ chartColor,
134
153
  checkError,
135
154
  choices,
136
155
  clearUnread,
@@ -144,6 +163,7 @@ export {
144
163
  createApplicationUpdateStore,
145
164
  createArrayBinding,
146
165
  createArraySourceScope,
166
+ createAssistantSession,
147
167
  createChoicesController,
148
168
  createClientListController,
149
169
  createCommandRegistry,
@@ -162,6 +182,7 @@ export {
162
182
  createLocaleSourceScope,
163
183
  createLockSession,
164
184
  createMicroStore,
185
+ createMissingKeyStore,
165
186
  createMutationOptions,
166
187
  createNominatimProvider,
167
188
  createNotificationStore,
@@ -178,6 +199,8 @@ export {
178
199
  createSavedQueriesController,
179
200
  createShowController,
180
201
  createStore,
202
+ createTopicHub,
203
+ createTourController,
181
204
  createTranslatableController,
182
205
  csvErrorRows,
183
206
  csvSchemaFields,
@@ -193,6 +216,7 @@ export {
193
216
  describeResource,
194
217
  detectJsonShape,
195
218
  downloadCSV,
219
+ echoAssistantTransport,
196
220
  editorStyles,
197
221
  email,
198
222
  englishMessages,
@@ -204,6 +228,8 @@ export {
204
228
  filterFormReflectShape,
205
229
  findPresetForTags,
206
230
  formatJsonValue,
231
+ formatPivotValue,
232
+ formatRelativeTime,
207
233
  fromEditorFeatures,
208
234
  fromJsonText,
209
235
  geoAreaM2,
@@ -216,12 +242,14 @@ export {
216
242
  getDirtyFormValues,
217
243
  getFilterFormValues,
218
244
  getInfiniteListOptions,
245
+ getJobActions,
219
246
  getListOptions,
220
247
  getLockOptions,
221
248
  getLocksOptions,
222
249
  getManyAggregateOptions,
223
250
  getManyOptions,
224
251
  getManyReferenceOptions,
252
+ getMetricDelta,
225
253
  getOneOptions,
226
254
  getPresenceInitials,
227
255
  getPrevNextParams,
@@ -230,6 +258,7 @@ export {
230
258
  getVisibleCommands,
231
259
  groupCalendarAgenda,
232
260
  groupCommands,
261
+ hasChartValues,
233
262
  hasCustomParams,
234
263
  hasPendingUndoables,
235
264
  hasSelfIntersection,
@@ -247,6 +276,8 @@ export {
247
276
  isLngLatBox,
248
277
  isRealtimeDataProvider,
249
278
  isRequired,
279
+ isSafeImageSrc,
280
+ isSafeLinkUrl,
250
281
  isSavedQueryActive,
251
282
  isTypingTarget,
252
283
  joinBasename,
@@ -284,6 +315,7 @@ export {
284
315
  normalizeFormError,
285
316
  number,
286
317
  omitCalendarRangeFilter,
318
+ onboardingTourKey,
287
319
  oneKey,
288
320
  overpassQueryOptions,
289
321
  parseCalendarDate,
@@ -292,6 +324,9 @@ export {
292
324
  parseLocation,
293
325
  patchedRecord,
294
326
  permissionsQueryOptions,
327
+ placeTourCard,
328
+ planJobCancel,
329
+ planJobRetry,
295
330
  planKanbanMove,
296
331
  polygonToBBox,
297
332
  presenceTopic,
@@ -313,6 +348,10 @@ export {
313
348
  resourceTopic,
314
349
  revalidateLogic,
315
350
  reverseGeocodeQueryOptions,
351
+ richTextBlockTypes,
352
+ richTextSanitizeOptions,
353
+ richTextStarterKitOptions,
354
+ richTextToolbarItems,
316
355
  rootSourceScope,
317
356
  runCsvImport,
318
357
  savedQueriesKey,
@@ -333,12 +372,16 @@ export {
333
372
  subscribeUnreadCount,
334
373
  tagToFilter,
335
374
  toCalendarEvents,
375
+ toCartesianRows,
336
376
  toCoordinate,
377
+ toDonutSlices,
337
378
  toEditorFeatures,
338
379
  toJsonText,
339
380
  toPresenceUser,
381
+ toTimelineEntries,
340
382
  toggleFilterValue,
341
383
  toggleHiddenColumn,
384
+ tourSpotlightPath,
342
385
  undoableCallbacks,
343
386
  undoableDeleteOptions,
344
387
  undoableUpdateOptions,
@@ -0,0 +1,34 @@
1
+ /** A box in viewport pixels. The adapters measure it; core touches no DOM. */
2
+ export interface TourRect {
3
+ top: number;
4
+ left: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export type TourPlacement = "auto" | "top" | "bottom" | "left" | "right";
9
+ type Side = Exclude<TourPlacement, "auto">;
10
+ export interface PlaceTourCardOptions {
11
+ /** `null` centres the card, for a step that points at nothing. */
12
+ target: TourRect | null;
13
+ card: {
14
+ width: number;
15
+ height: number;
16
+ };
17
+ viewport: {
18
+ width: number;
19
+ height: number;
20
+ };
21
+ placement: TourPlacement;
22
+ /** Gap between card and target, and the least distance to a viewport edge. */
23
+ margin?: number;
24
+ }
25
+ export interface TourCardPosition {
26
+ /** The card's top-left corner. */
27
+ top: number;
28
+ left: number;
29
+ side: Side;
30
+ }
31
+ export declare function placeTourCard({ target, card, viewport, placement, margin, }: PlaceTourCardOptions): TourCardPosition;
32
+ /** A CSS `clip-path` that fills the page except the target's rect. */
33
+ export declare function tourSpotlightPath(target: TourRect): string;
34
+ export {};
@@ -0,0 +1,82 @@
1
+ const SIDES = ["bottom", "top", "right", "left"];
2
+ const OPPOSITE = {
3
+ top: "bottom",
4
+ bottom: "top",
5
+ left: "right",
6
+ right: "left"
7
+ };
8
+ function placeTourCard({
9
+ target,
10
+ card,
11
+ viewport,
12
+ placement,
13
+ margin = 12
14
+ }) {
15
+ if (!target) {
16
+ return {
17
+ top: (viewport.height - card.height) / 2,
18
+ left: (viewport.width - card.width) / 2,
19
+ side: placement === "auto" ? "bottom" : placement
20
+ };
21
+ }
22
+ const room = {
23
+ top: target.top,
24
+ bottom: viewport.height - (target.top + target.height),
25
+ left: target.left,
26
+ right: viewport.width - (target.left + target.width)
27
+ };
28
+ const needed = (side2) => (side2 === "top" || side2 === "bottom" ? card.height : card.width) + margin * 2;
29
+ const fits = (side2) => room[side2] >= needed(side2);
30
+ let side;
31
+ if (placement === "auto") {
32
+ const roomiest = (candidates) => candidates.reduce(
33
+ (best, next) => room[next] > room[best] ? next : best
34
+ );
35
+ const fitting = SIDES.filter(fits);
36
+ side = roomiest(fitting.length > 0 ? fitting : SIDES);
37
+ } else {
38
+ side = !fits(placement) && fits(OPPOSITE[placement]) ? OPPOSITE[placement] : placement;
39
+ }
40
+ const centreX = target.left + target.width / 2 - card.width / 2;
41
+ const centreY = target.top + target.height / 2 - card.height / 2;
42
+ let top;
43
+ let left;
44
+ switch (side) {
45
+ case "bottom":
46
+ top = target.top + target.height + margin;
47
+ left = centreX;
48
+ break;
49
+ case "top":
50
+ top = target.top - margin - card.height;
51
+ left = centreX;
52
+ break;
53
+ case "right":
54
+ top = centreY;
55
+ left = target.left + target.width + margin;
56
+ break;
57
+ case "left":
58
+ top = centreY;
59
+ left = target.left - margin - card.width;
60
+ break;
61
+ }
62
+ return {
63
+ top: Math.max(
64
+ margin,
65
+ Math.min(top, viewport.height - card.height - margin)
66
+ ),
67
+ left: Math.max(
68
+ margin,
69
+ Math.min(left, viewport.width - card.width - margin)
70
+ ),
71
+ side
72
+ };
73
+ }
74
+ function tourSpotlightPath(target) {
75
+ const right = target.left + target.width;
76
+ const bottom = target.top + target.height;
77
+ return `polygon(0% 0%, 0% 100%, ${target.left}px 100%, ${target.left}px ${target.top}px, ${right}px ${target.top}px, ${right}px ${bottom}px, ${target.left}px ${bottom}px, ${target.left}px 100%, 100% 100%, 100% 0%)`;
78
+ }
79
+ export {
80
+ placeTourCard,
81
+ tourSpotlightPath
82
+ };
@@ -0,0 +1,25 @@
1
+ import { type MicroStore } from "../store/micro-store.js";
2
+ import type { CheloneStore } from "../store/store.js";
3
+ /** Where the onboarding tour keeps its done flag in a `CheloneStore`. */
4
+ export declare function onboardingTourKey(id: string): string;
5
+ export interface TourState {
6
+ active: boolean;
7
+ index: number;
8
+ }
9
+ export type TourEnd = "finished" | "skipped";
10
+ export interface TourControllerOptions {
11
+ id: string;
12
+ stepCount: number;
13
+ store: CheloneStore;
14
+ /** Open on the first subscribe while the done flag is not `true`. */
15
+ autoStart?: boolean;
16
+ onComplete?: (reason: TourEnd) => void;
17
+ }
18
+ export interface TourController extends MicroStore<TourState> {
19
+ start(): void;
20
+ next(): void;
21
+ back(): void;
22
+ skip(): void;
23
+ finish(): void;
24
+ }
25
+ export declare function createTourController({ id, stepCount, store, autoStart, onComplete, }: TourControllerOptions): TourController;