@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.
Files changed (255) hide show
  1. package/dist/assistant/assistant-session.d.ts +6 -0
  2. package/dist/assistant/assistant-session.js +204 -181
  3. package/dist/assistant/echo-transport.js +26 -29
  4. package/dist/assistant/http-transport.d.ts +10 -0
  5. package/dist/assistant/http-transport.js +98 -0
  6. package/dist/assistant/types.d.ts +1 -7
  7. package/dist/auth/access-control.d.ts +13 -5
  8. package/dist/auth/access-control.js +25 -21
  9. package/dist/auth/auth-options.d.ts +23 -17
  10. package/dist/auth/auth-options.js +82 -48
  11. package/dist/auth/permission-matrix.d.ts +12 -0
  12. package/dist/auth/permission-matrix.js +67 -0
  13. package/dist/auth/types.d.ts +14 -4
  14. package/dist/block-editor/block-document.d.ts +64 -0
  15. package/dist/block-editor/block-document.js +147 -0
  16. package/dist/block-editor/data-blocks.d.ts +63 -0
  17. package/dist/block-editor/data-blocks.js +117 -0
  18. package/dist/chart/chart-data.js +46 -44
  19. package/dist/command-menu/hotkey.js +58 -47
  20. package/dist/command-menu/recents.d.ts +4 -0
  21. package/dist/command-menu/recents.js +12 -11
  22. package/dist/command-menu/registry.d.ts +9 -5
  23. package/dist/command-menu/registry.js +36 -46
  24. package/dist/controller/calendar-dates.d.ts +12 -0
  25. package/dist/controller/calendar-dates.js +94 -113
  26. package/dist/controller/calendar-events.js +93 -88
  27. package/dist/controller/client-list-controller.d.ts +2 -2
  28. package/dist/controller/client-list-controller.js +251 -254
  29. package/dist/controller/data-table-columns.d.ts +2 -0
  30. package/dist/controller/data-table-columns.js +50 -56
  31. package/dist/controller/deep-equal.d.ts +1 -0
  32. package/dist/controller/deep-equal.js +14 -0
  33. package/dist/controller/filter-toggle.js +36 -44
  34. package/dist/controller/in-place-editor.d.ts +43 -0
  35. package/dist/controller/in-place-editor.js +43 -0
  36. package/dist/controller/infinite-list-controller.js +219 -189
  37. package/dist/controller/inspector.d.ts +55 -0
  38. package/dist/controller/inspector.js +70 -0
  39. package/dist/controller/job-monitor.d.ts +10 -4
  40. package/dist/controller/job-monitor.js +46 -47
  41. package/dist/controller/kanban-board.js +45 -24
  42. package/dist/controller/list-controller.d.ts +8 -5
  43. package/dist/controller/list-controller.js +447 -400
  44. package/dist/controller/list-params.js +96 -87
  45. package/dist/controller/pivot-grid.d.ts +4 -4
  46. package/dist/controller/pivot-grid.js +89 -95
  47. package/dist/controller/prev-next.d.ts +2 -2
  48. package/dist/controller/prev-next.js +74 -54
  49. package/dist/controller/record-controllers.d.ts +14 -6
  50. package/dist/controller/record-controllers.js +288 -257
  51. package/dist/controller/record-diff.d.ts +21 -0
  52. package/dist/controller/record-diff.js +50 -0
  53. package/dist/controller/record-timeline.d.ts +5 -5
  54. package/dist/controller/record-timeline.js +42 -30
  55. package/dist/controller/record-tree.js +57 -47
  56. package/dist/controller/record-workflow.d.ts +38 -16
  57. package/dist/controller/record-workflow.js +85 -64
  58. package/dist/controller/reference-many-controller.d.ts +2 -0
  59. package/dist/controller/reference-many-controller.js +199 -192
  60. package/dist/controller/reference-one-controller.d.ts +1 -1
  61. package/dist/controller/reference-one-controller.js +63 -56
  62. package/dist/controller/saved-queries.js +104 -91
  63. package/dist/controller/translate-fallback.js +10 -6
  64. package/dist/csv/export.d.ts +4 -3
  65. package/dist/csv/export.js +43 -40
  66. package/dist/csv/import-controller.d.ts +4 -0
  67. package/dist/csv/import-controller.js +189 -169
  68. package/dist/csv/match-headers.js +29 -22
  69. package/dist/csv/parse-with.js +60 -54
  70. package/dist/csv/run-import.js +69 -72
  71. package/dist/csv/validate-rows.d.ts +1 -1
  72. package/dist/csv/validate-rows.js +65 -52
  73. package/dist/data/cache-ops.d.ts +5 -4
  74. package/dist/data/cache-ops.js +208 -188
  75. package/dist/data/combine-data-providers.js +25 -23
  76. package/dist/data/data-provider-log.d.ts +45 -0
  77. package/dist/data/data-provider-log.js +93 -0
  78. package/dist/data/errors.js +14 -10
  79. package/dist/data/fake-provider.d.ts +6 -3
  80. package/dist/data/fake-provider.js +135 -114
  81. package/dist/data/fetch-utils.js +61 -44
  82. package/dist/data/filter-branch.d.ts +5 -0
  83. package/dist/data/filter-branch.js +10 -0
  84. package/dist/data/get-many-aggregate.js +84 -76
  85. package/dist/data/http-error.js +17 -12
  86. package/dist/data/keys.js +50 -36
  87. package/dist/data/mutation-options.d.ts +14 -9
  88. package/dist/data/mutation-options.js +93 -109
  89. package/dist/data/query-options.js +73 -68
  90. package/dist/data/remove-empty.d.ts +3 -0
  91. package/dist/data/remove-empty.js +11 -0
  92. package/dist/data/undoable.d.ts +2 -2
  93. package/dist/data/undoable.js +190 -174
  94. package/dist/data/with-lifecycle-callbacks.d.ts +45 -17
  95. package/dist/data/with-lifecycle-callbacks.js +66 -52
  96. package/dist/environment/application-update-store.js +58 -55
  97. package/dist/environment/offline-store.js +21 -21
  98. package/dist/form/array-binding.d.ts +30 -11
  99. package/dist/form/array-binding.js +184 -166
  100. package/dist/form/choice-ids.d.ts +7 -0
  101. package/dist/form/choice-ids.js +11 -0
  102. package/dist/form/choices-controller.d.ts +22 -2
  103. package/dist/form/choices-controller.js +315 -275
  104. package/dist/form/date-format.d.ts +38 -0
  105. package/dist/form/date-format.js +89 -0
  106. package/dist/form/dirty-values.d.ts +2 -2
  107. package/dist/form/dirty-values.js +22 -11
  108. package/dist/form/duration.d.ts +22 -0
  109. package/dist/form/duration.js +49 -0
  110. package/dist/form/edit-create-form.d.ts +12 -5
  111. package/dist/form/edit-create-form.js +243 -188
  112. package/dist/form/event-value.d.ts +6 -0
  113. package/dist/form/event-value.js +17 -0
  114. package/dist/form/field-error.d.ts +14 -0
  115. package/dist/form/field-error.js +28 -0
  116. package/dist/form/field-name.d.ts +20 -0
  117. package/dist/form/field-name.js +6 -0
  118. package/dist/form/filter-form-values.js +63 -49
  119. package/dist/form/form-controller.d.ts +9 -1
  120. package/dist/form/form-controller.js +165 -160
  121. package/dist/form/form-groups.d.ts +4 -3
  122. package/dist/form/form-groups.js +79 -79
  123. package/dist/form/form-handle.d.ts +175 -0
  124. package/dist/form/form-handle.js +68 -0
  125. package/dist/form/input-binding.d.ts +56 -31
  126. package/dist/form/input-binding.js +171 -118
  127. package/dist/form/input-values.d.ts +140 -0
  128. package/dist/form/input-values.js +206 -0
  129. package/dist/form/json-text.d.ts +11 -0
  130. package/dist/form/json-text.js +62 -37
  131. package/dist/form/save-pipeline.d.ts +6 -8
  132. package/dist/form/save-pipeline.js +91 -82
  133. package/dist/form/set-form-values.d.ts +6 -0
  134. package/dist/form/set-form-values.js +10 -0
  135. package/dist/form/source.js +97 -65
  136. package/dist/form/text-of.d.ts +2 -0
  137. package/dist/form/text-of.js +7 -0
  138. package/dist/form/validators.d.ts +58 -19
  139. package/dist/form/validators.js +97 -71
  140. package/dist/geo/bbox.d.ts +5 -4
  141. package/dist/geo/bbox.js +69 -48
  142. package/dist/geo/bounds.d.ts +14 -3
  143. package/dist/geo/bounds.js +98 -68
  144. package/dist/geo/constraints.js +88 -93
  145. package/dist/geo/coordinates.d.ts +10 -0
  146. package/dist/geo/coordinates.js +44 -23
  147. package/dist/geo/editor.d.ts +13 -13
  148. package/dist/geo/editor.js +176 -153
  149. package/dist/geo/geocoding.d.ts +4 -4
  150. package/dist/geo/geocoding.js +38 -41
  151. package/dist/geo/geojson.d.ts +12 -74
  152. package/dist/geo/geojson.js +52 -40
  153. package/dist/geo/geometry-math.d.ts +4 -4
  154. package/dist/geo/geometry-math.js +100 -93
  155. package/dist/geo/index.d.ts +9 -8
  156. package/dist/geo/map-layers.d.ts +42 -7
  157. package/dist/geo/map-layers.js +88 -62
  158. package/dist/geo/map-style.d.ts +12 -0
  159. package/dist/geo/map-style.js +43 -32
  160. package/dist/geo/messages.js +48 -45
  161. package/dist/geo/nominatim.js +88 -80
  162. package/dist/geo/osm-presets.d.ts +4 -3
  163. package/dist/geo/osm-presets.js +108 -86
  164. package/dist/geo/osm-tags.js +14 -12
  165. package/dist/geo/overpass.d.ts +14 -2
  166. package/dist/geo/overpass.js +83 -90
  167. package/dist/geo/shape-value.d.ts +9 -5
  168. package/dist/geo/shape-value.js +169 -146
  169. package/dist/geo/snap-to-roads.d.ts +3 -3
  170. package/dist/geo/snap-to-roads.js +55 -50
  171. package/dist/geo/throttle.js +36 -39
  172. package/dist/guards.d.ts +44 -0
  173. package/dist/guards.js +77 -0
  174. package/dist/i18n/default-messages.js +34 -29
  175. package/dist/i18n/english-messages.d.ts +172 -0
  176. package/dist/i18n/english-messages.js +359 -189
  177. package/dist/i18n/i18n.d.ts +2 -2
  178. package/dist/i18n/i18n.js +47 -60
  179. package/dist/i18n/inflection.d.ts +34 -0
  180. package/dist/i18n/inflection.js +82 -0
  181. package/dist/i18n/messages.d.ts +10 -2
  182. package/dist/i18n/messages.js +17 -4
  183. package/dist/i18n/missing-keys.d.ts +4 -0
  184. package/dist/i18n/missing-keys.js +70 -62
  185. package/dist/i18n/translatable.d.ts +16 -1
  186. package/dist/i18n/translatable.js +40 -47
  187. package/dist/index.d.ts +87 -39
  188. package/dist/index.js +54 -301
  189. package/dist/json/deep-equal.d.ts +8 -0
  190. package/dist/json/deep-equal.js +24 -0
  191. package/dist/json/strip-json-comments.js +38 -42
  192. package/dist/noop.d.ts +2 -0
  193. package/dist/noop.js +4 -0
  194. package/dist/notification/error-message.d.ts +2 -0
  195. package/dist/notification/error-message.js +10 -0
  196. package/dist/notification/notification-store.d.ts +3 -2
  197. package/dist/notification/notification-store.js +41 -45
  198. package/dist/onboarding-tour/placement.d.ts +2 -0
  199. package/dist/onboarding-tour/placement.js +65 -78
  200. package/dist/onboarding-tour/tour-controller.js +46 -54
  201. package/dist/realtime/add-events-for-mutations.js +75 -81
  202. package/dist/realtime/announce-lock.js +16 -13
  203. package/dist/realtime/broadcast-channel-transport.js +65 -59
  204. package/dist/realtime/copy-members.js +22 -14
  205. package/dist/realtime/in-memory-lock-provider.js +40 -48
  206. package/dist/realtime/live.js +95 -101
  207. package/dist/realtime/lock-options.js +16 -16
  208. package/dist/realtime/lock-session.js +91 -78
  209. package/dist/realtime/memory-transport.js +25 -25
  210. package/dist/realtime/presence.js +120 -122
  211. package/dist/realtime/realtime-data-provider.d.ts +10 -0
  212. package/dist/realtime/realtime-data-provider.js +45 -42
  213. package/dist/realtime/reconnect-backoff.js +17 -0
  214. package/dist/realtime/sse-transport.d.ts +31 -0
  215. package/dist/realtime/sse-transport.js +235 -0
  216. package/dist/realtime/status-store.js +23 -28
  217. package/dist/realtime/topic-hub.js +62 -71
  218. package/dist/realtime/topics.js +10 -12
  219. package/dist/realtime/types.js +10 -12
  220. package/dist/realtime/unread-count.js +21 -21
  221. package/dist/realtime/websocket-transport.d.ts +32 -0
  222. package/dist/realtime/websocket-transport.js +306 -0
  223. package/dist/resource/describe-resource.d.ts +2 -0
  224. package/dist/resource/describe-resource.js +247 -219
  225. package/dist/resource/get-at-path.js +29 -14
  226. package/dist/resource/identifier.d.ts +18 -0
  227. package/dist/resource/identifier.js +27 -0
  228. package/dist/resource/record.d.ts +4 -0
  229. package/dist/resource/record.js +10 -0
  230. package/dist/resource/register.d.ts +7 -0
  231. package/dist/resource/registry-store.d.ts +45 -15
  232. package/dist/resource/registry-store.js +67 -60
  233. package/dist/resource/registry.d.ts +10 -0
  234. package/dist/resource/registry.js +8 -4
  235. package/dist/resource/source-path.d.ts +23 -2
  236. package/dist/rich-text/rich-text-extras.d.ts +134 -0
  237. package/dist/rich-text/rich-text-extras.js +181 -0
  238. package/dist/rich-text/rich-text-image.d.ts +124 -0
  239. package/dist/rich-text/rich-text-image.js +163 -0
  240. package/dist/rich-text/rich-text.d.ts +6 -0
  241. package/dist/rich-text/rich-text.js +125 -88
  242. package/dist/router/location.d.ts +24 -4
  243. package/dist/router/location.js +43 -18
  244. package/dist/router/match.js +47 -39
  245. package/dist/router/paths.js +40 -34
  246. package/dist/router/record-from-location.d.ts +1 -1
  247. package/dist/router/record-from-location.js +25 -17
  248. package/dist/store/adapters.js +51 -55
  249. package/dist/store/micro-store.js +57 -59
  250. package/dist/store/shallow-equal.d.ts +12 -0
  251. package/dist/store/shallow-equal.js +20 -0
  252. package/dist/store/store.js +54 -57
  253. package/dist/ui-defaults.d.ts +15 -0
  254. package/dist/ui-defaults.js +17 -0
  255. package/package.json +13 -11
@@ -0,0 +1,55 @@
1
+ import { type MicroStore } from "../store/micro-store.js";
2
+ import { type DataTableColumnInfo } from "./data-table-columns.js";
3
+ /**
4
+ * What the panel edits. `editor` is generic so each adapter stores its own
5
+ * editor type (a React node, a Vue component).
6
+ */
7
+ export interface InspectorSelection<TEditor> {
8
+ key: string;
9
+ title?: string;
10
+ editor: TEditor;
11
+ }
12
+ export interface InspectorState<TEditor> {
13
+ enabled: boolean;
14
+ selected: InspectorSelection<TEditor> | null;
15
+ }
16
+ export interface Inspector<TEditor> {
17
+ store: MicroStore<InspectorState<TEditor>>;
18
+ enable(): void;
19
+ /** Also clears the selection. */
20
+ disable(): void;
21
+ toggle(): void;
22
+ /** Replaces the selection while enabled and does nothing while disabled. */
23
+ select(selection: InspectorSelection<TEditor>): void;
24
+ /** Clears the selection only when its key is `key`, so a stale unmount cannot clear a newer one. */
25
+ release(key: string): void;
26
+ }
27
+ export declare function createInspector<TEditor = unknown>(): Inspector<TEditor>;
28
+ export declare const inspectorPositionKey = "chelone.inspector.position";
29
+ /** The panel's width in pixels. */
30
+ export declare const PANEL_WIDTH = 320;
31
+ /** How far one arrow key moves the panel, in pixels. */
32
+ export declare const INSPECTOR_KEY_STEP = 16;
33
+ /** The message key a `<Configurable>`'s open button falls back to. */
34
+ export declare const INSPECTOR_OPEN_LABEL = "chelone.inspector.customize";
35
+ export interface InspectorPosition {
36
+ x: number;
37
+ y: number;
38
+ }
39
+ export interface InspectorViewport {
40
+ viewportWidth: number;
41
+ viewportHeight: number;
42
+ panelWidth: number;
43
+ margin?: number;
44
+ handleHeight?: number;
45
+ }
46
+ /**
47
+ * Keeps the panel's drag handle on screen. A missing or non-finite position
48
+ * gives the top right corner.
49
+ */
50
+ export declare function clampInspectorPosition(position: InspectorPosition | null | undefined, { viewportWidth, viewportHeight, panelWidth, margin, handleHeight, }: InspectorViewport): InspectorPosition;
51
+ export declare function defaultConfigurableInputsStoreKey(resource: string): string;
52
+ export declare function configurableInputColumns(inputs: readonly {
53
+ source?: unknown;
54
+ label?: unknown;
55
+ }[]): DataTableColumnInfo[];
@@ -0,0 +1,70 @@
1
+ import { createMicroStore } from "../store/micro-store.js";
2
+ import { getDataTableColumnId } from "./data-table-columns.js";
3
+ // src/controller/inspector.ts
4
+ function createInspector() {
5
+ const store = createMicroStore({
6
+ enabled: false,
7
+ selected: null
8
+ });
9
+ const enable = () => store.setState({ enabled: true });
10
+ const disable = () => store.setState({
11
+ enabled: false,
12
+ selected: null
13
+ });
14
+ return {
15
+ store,
16
+ enable,
17
+ disable,
18
+ toggle() {
19
+ if (store.getSnapshot().enabled) disable();
20
+ else enable();
21
+ },
22
+ select(selection) {
23
+ if (!store.getSnapshot().enabled) return;
24
+ store.setState({ selected: selection });
25
+ },
26
+ release(key) {
27
+ if (store.getSnapshot().selected?.key !== key) return;
28
+ store.setState({ selected: null });
29
+ }
30
+ };
31
+ }
32
+ var inspectorPositionKey = "chelone.inspector.position";
33
+ /** The panel's width in pixels. */
34
+ var PANEL_WIDTH = 320;
35
+ /** How far one arrow key moves the panel, in pixels. */
36
+ var INSPECTOR_KEY_STEP = 16;
37
+ /** The message key a `<Configurable>`'s open button falls back to. */
38
+ var INSPECTOR_OPEN_LABEL = "chelone.inspector.customize";
39
+ var clamp = (value, min, max) => Math.min(Math.max(value, min), Math.max(min, max));
40
+ /**
41
+ * Keeps the panel's drag handle on screen. A missing or non-finite position
42
+ * gives the top right corner.
43
+ */
44
+ function clampInspectorPosition(position, { viewportWidth, viewportHeight, panelWidth, margin = 8, handleHeight = 48 }) {
45
+ const maxX = viewportWidth - panelWidth - margin;
46
+ const maxY = viewportHeight - handleHeight;
47
+ if (!position || !Number.isFinite(position.x) || !Number.isFinite(position.y)) return {
48
+ x: clamp(maxX, margin, maxX),
49
+ y: margin
50
+ };
51
+ return {
52
+ x: clamp(position.x, margin, maxX),
53
+ y: clamp(position.y, margin, maxY)
54
+ };
55
+ }
56
+ function defaultConfigurableInputsStoreKey(resource) {
57
+ return `${resource}.inputs`;
58
+ }
59
+ function configurableInputColumns(inputs) {
60
+ return inputs.map(({ source, label }, index) => {
61
+ const column = { id: getDataTableColumnId({
62
+ source,
63
+ label
64
+ }) ?? `input-${index}` };
65
+ if (typeof source === "string") column.source = source;
66
+ if (typeof label === "string") column.label = label;
67
+ return column;
68
+ });
69
+ }
70
+ export { INSPECTOR_KEY_STEP, INSPECTOR_OPEN_LABEL, PANEL_WIDTH, clampInspectorPosition, configurableInputColumns, createInspector, defaultConfigurableInputsStoreKey, inspectorPositionKey };
@@ -11,9 +11,9 @@ import type { ResourceRecord } from "../resource/record.js";
11
11
  import type { SourceKey } from "../resource/source-path.js";
12
12
  /** The monitor's tabs, in order. One `buildKanbanBuckets` column per status. */
13
13
  export declare const DEFAULT_JOB_TABS: readonly ["running", "queued", "failed", "done"];
14
- export interface JobActionOptions<TRecord = Record<string, unknown>> {
14
+ export interface JobActionOptions<TRecord extends object> {
15
15
  /** Record field holding the job status, a top-level key. Default `"status"`. */
16
- statusSource?: SourceKey<TRecord>;
16
+ statusSource?: keyof TRecord & string;
17
17
  /** Statuses a job can be retried from. Default `["failed"]`. */
18
18
  retryFrom?: readonly string[];
19
19
  /** Statuses a job can be cancelled from. Default `["running", "queued"]`. */
@@ -32,10 +32,16 @@ export interface JobActions {
32
32
  /** The arguments of one `update` call, ready to hand to a data provider. */
33
33
  export interface JobPlan<TRecord> {
34
34
  id: Identifier;
35
- data: Record<string, string>;
35
+ data: Partial<TRecord>;
36
36
  previousData: TRecord;
37
37
  }
38
- export declare function getJobActions<TRecord = Record<string, unknown>>(record: TRecord & object, options?: JobActionOptions<TRecord>): JobActions;
38
+ /**
39
+ * The status key a monitor reads: `source`, or `"status"`. `SourceKey` is
40
+ * `keyof TRecord & string` for a typed record and `string` for a loose one,
41
+ * whose keys are every string, so it is always a key of `TRecord`.
42
+ */
43
+ export declare function jobStatusSource<TRecord extends object>(source?: SourceKey<TRecord>): keyof TRecord & string;
44
+ export declare function getJobActions<TRecord extends object>(record: TRecord & object, options?: JobActionOptions<TRecord>): JobActions;
39
45
  /** The `update` that retries the job, or `null` when it cannot be retried. */
40
46
  export declare function planJobRetry<TRecord extends ResourceRecord = ResourceRecord>(record: TRecord, options?: JobActionOptions<TRecord>): JobPlan<TRecord> | null;
41
47
  /** The `update` that cancels the job, or `null` when it cannot be cancelled. */
@@ -1,59 +1,58 @@
1
1
  import { getAllowedTransitions } from "./record-workflow.js";
2
- const DEFAULT_JOB_TABS = [
3
- "running",
4
- "queued",
5
- "failed",
6
- "done"
2
+ // src/controller/job-monitor.ts
3
+ /** The monitor's tabs, in order. One `buildKanbanBuckets` column per status. */
4
+ var DEFAULT_JOB_TABS = [
5
+ "running",
6
+ "queued",
7
+ "failed",
8
+ "done"
7
9
  ];
8
10
  function canMove(record, source, from, to) {
9
- const transitions = Object.fromEntries(from.map((status) => [status, [to]]));
10
- const { current, allowed } = getAllowedTransitions(record, {
11
- source,
12
- transitions
13
- });
14
- return { status: current, allowed: allowed.includes(to) };
11
+ const transitions = Object.fromEntries(from.map((status) => [status, [to]]));
12
+ const { current, allowed } = getAllowedTransitions(record, {
13
+ source,
14
+ transitions
15
+ });
16
+ return {
17
+ status: current,
18
+ allowed: allowed.includes(to)
19
+ };
20
+ }
21
+ /**
22
+ * The status key a monitor reads: `source`, or `"status"`. `SourceKey` is
23
+ * `keyof TRecord & string` for a typed record and `string` for a loose one,
24
+ * whose keys are every string, so it is always a key of `TRecord`.
25
+ */
26
+ function jobStatusSource(source) {
27
+ return source ?? "status";
15
28
  }
16
29
  function getJobActions(record, options = {}) {
17
- const {
18
- statusSource = "status",
19
- retryFrom = ["failed"],
20
- cancelFrom = ["running", "queued"],
21
- retryValue = "queued",
22
- cancelValue = "cancelled"
23
- } = options;
24
- const retry = canMove(record, statusSource, retryFrom, retryValue);
25
- const cancel = canMove(record, statusSource, cancelFrom, cancelValue);
26
- return {
27
- status: retry.status,
28
- canRetry: retry.allowed,
29
- canCancel: cancel.allowed
30
- };
30
+ const { statusSource = "status", retryFrom = ["failed"], cancelFrom = ["running", "queued"], retryValue = "queued", cancelValue = "cancelled" } = options;
31
+ const retry = canMove(record, statusSource, retryFrom, retryValue);
32
+ const cancel = canMove(record, statusSource, cancelFrom, cancelValue);
33
+ return {
34
+ status: retry.status,
35
+ canRetry: retry.allowed,
36
+ canCancel: cancel.allowed
37
+ };
31
38
  }
32
39
  function plan(record, source, value, allowed) {
33
- if (!allowed) return null;
34
- return { id: record.id, data: { [source]: value }, previousData: record };
40
+ if (!allowed) return null;
41
+ const data = { [source]: value };
42
+ return {
43
+ id: record.id,
44
+ data,
45
+ previousData: record
46
+ };
35
47
  }
48
+ /** The `update` that retries the job, or `null` when it cannot be retried. */
36
49
  function planJobRetry(record, options = {}) {
37
- const { statusSource = "status", retryValue = "queued" } = options;
38
- return plan(
39
- record,
40
- statusSource,
41
- retryValue,
42
- getJobActions(record, options).canRetry
43
- );
50
+ const { statusSource = "status", retryValue = "queued" } = options;
51
+ return plan(record, statusSource, retryValue, getJobActions(record, options).canRetry);
44
52
  }
53
+ /** The `update` that cancels the job, or `null` when it cannot be cancelled. */
45
54
  function planJobCancel(record, options = {}) {
46
- const { statusSource = "status", cancelValue = "cancelled" } = options;
47
- return plan(
48
- record,
49
- statusSource,
50
- cancelValue,
51
- getJobActions(record, options).canCancel
52
- );
55
+ const { statusSource = "status", cancelValue = "cancelled" } = options;
56
+ return plan(record, statusSource, cancelValue, getJobActions(record, options).canCancel);
53
57
  }
54
- export {
55
- DEFAULT_JOB_TABS,
56
- getJobActions,
57
- planJobCancel,
58
- planJobRetry
59
- };
58
+ export { DEFAULT_JOB_TABS, getJobActions, jobStatusSource, planJobCancel, planJobRetry };
@@ -1,30 +1,51 @@
1
+ // src/controller/kanban-board.ts
2
+ /**
3
+ * The column key a record sits under: its group value as a string, with a
4
+ * missing or null value reading as `""`. A top-level key, because a move can
5
+ * only write `{ [source]: value }` — as in {@link getAllowedTransitions}.
6
+ * Read through `Reflect.get`: `SourceKey<R>` of a generic record is a
7
+ * deferred type, so `record[groupSource]` would not typecheck.
8
+ */
1
9
  function bucketKey(record, groupSource) {
2
- const value = record[groupSource];
3
- return String(value ?? "");
10
+ return String(Reflect.get(record, groupSource) ?? "");
4
11
  }
12
+ /**
13
+ * One bucket per column, in column order, empty columns included. A record
14
+ * lands in the column whose id is its group key; a record that names no column
15
+ * is in no bucket, and records keep list order inside a bucket. A repeated
16
+ * column id keeps the first column's records and leaves the later one empty.
17
+ */
5
18
  function buildKanbanBuckets(records, groupSource, columns) {
6
- const buckets = columns.map((column) => ({
7
- column,
8
- records: []
9
- }));
10
- const bucketOf = /* @__PURE__ */ new Map();
11
- columns.forEach((column, index) => {
12
- if (!bucketOf.has(column.id)) bucketOf.set(column.id, index);
13
- });
14
- for (const record of records) {
15
- const index = bucketOf.get(bucketKey(record, groupSource));
16
- if (index === void 0) continue;
17
- buckets[index].records.push(record);
18
- }
19
- return buckets;
19
+ const buckets = columns.map((column) => ({
20
+ column,
21
+ records: []
22
+ }));
23
+ const bucketOf = /* @__PURE__ */ new Map();
24
+ columns.forEach((column, index) => {
25
+ if (!bucketOf.has(column.id)) bucketOf.set(column.id, index);
26
+ });
27
+ for (const record of records) {
28
+ const index = bucketOf.get(bucketKey(record, groupSource));
29
+ if (index === void 0) continue;
30
+ const bucket = buckets[index];
31
+ if (bucket) bucket.records.push(record);
32
+ }
33
+ return buckets;
20
34
  }
35
+ /**
36
+ * The update a drop into `targetColumnId` asks for, or `null` when there is
37
+ * nothing to write: the target is not a column, or the record already sits in
38
+ * it. A drop that writes nothing still fires a data-provider `update` on every
39
+ * board that re-renders on a dropped drag, so the adapters ask here first.
40
+ */
21
41
  function planKanbanMove(record, groupSource, columns, targetColumnId) {
22
- if (!columns.some((column) => column.id === targetColumnId)) return null;
23
- if (bucketKey(record, groupSource) === targetColumnId) return null;
24
- const data = { [groupSource]: targetColumnId };
25
- return { id: record.id, data, previousData: record };
42
+ if (!columns.some((column) => column.id === targetColumnId)) return null;
43
+ if (bucketKey(record, groupSource) === targetColumnId) return null;
44
+ const data = { [groupSource]: targetColumnId };
45
+ return {
46
+ id: record.id,
47
+ data,
48
+ previousData: record
49
+ };
26
50
  }
27
- export {
28
- buildKanbanBuckets,
29
- planKanbanMove
30
- };
51
+ export { buildKanbanBuckets, planKanbanMove };
@@ -19,7 +19,7 @@ export interface ListControllerState<TRecord> {
19
19
  pageInfo: PageInfo | undefined;
20
20
  isPending: boolean;
21
21
  isFetching: boolean;
22
- error: unknown;
22
+ error: Error | null;
23
23
  hasNextPage: boolean | undefined;
24
24
  hasPreviousPage: boolean | undefined;
25
25
  }
@@ -76,6 +76,9 @@ export interface ListControllerOptions {
76
76
  storeKey?: string | false;
77
77
  enabled?: boolean;
78
78
  }
79
+ /** The `perPage` a list starts at when nothing is persisted or in the URL. The single definition: `prev-next` and both adapters read this. */
80
+ export declare const DEFAULT_PER_PAGE = 10;
81
+ /** Debounce delay for `setFilters(..., debounced=true)` when no `debounceMs` option is given. Shared with the reference-many and choices controllers. */
79
82
  export declare const DEFAULT_DEBOUNCE_MS = 500;
80
83
  export declare const DEFAULT_SELECT_ALL_LIMIT = 250;
81
84
  /**
@@ -108,17 +111,17 @@ export declare function runSelectAll(notifications: NotificationStore | undefine
108
111
  * again after a success can say so.
109
112
  */
110
113
  export declare function createErrorAnnouncer(notifications: NotificationStore | undefined): {
111
- announce(error: unknown): void;
114
+ announce(error: Error | null): void;
112
115
  rearm(): void;
113
116
  };
114
117
  /** `hasNextPage`/`hasPreviousPage` from the provider's `pageInfo` or, failing that, the total. */
115
- export declare function pageFlags(page: number, perPage: number, total: number | undefined, pageInfo: PageInfo | undefined): Pick<ListControllerState<unknown>, "hasNextPage" | "hasPreviousPage">;
118
+ export declare function pageFlags(page: number, perPage: number, total: number | undefined, pageInfo: PageInfo | undefined): Pick<ListControllerState<ResourceRecord>, "hasNextPage" | "hasPreviousPage">;
116
119
  /**
117
120
  * The page an out-of-range state should move to, or undefined when it is in
118
121
  * range. Only a SETTLED result may move past page 1, so a reset-induced
119
122
  * refetch can never trigger another reset.
120
123
  */
121
- export declare function resetPageTarget(s: Pick<ListControllerState<unknown>, "page" | "perPage" | "total" | "data" | "isPending" | "isFetching">): number | undefined;
124
+ export declare function resetPageTarget(s: Pick<ListControllerState<ResourceRecord>, "page" | "perPage" | "total" | "data" | "isPending" | "isFetching">): number | undefined;
122
125
  /**
123
126
  * Vanilla list controller: one QueryObserver mapped into a micro-store.
124
127
  *
@@ -142,7 +145,7 @@ export declare function resetPageTarget(s: Pick<ListControllerState<unknown>, "p
142
145
  * The actions of a list controller, for an adapter to spread next to its own
143
146
  * reactive state. They are the same functions across state changes.
144
147
  */
145
- export declare function listControllerActions(controller: Omit<ListController<unknown>, keyof MicroStore<ListControllerState<unknown>> | "defaultPerPage">): {
148
+ export declare function listControllerActions(controller: Omit<ListController<ResourceRecord>, keyof MicroStore<ListControllerState<ResourceRecord>> | "defaultPerPage">): {
146
149
  setPage: (page: number) => void;
147
150
  setPerPage: (perPage: number) => void;
148
151
  setSort: (sort: SortPayload | SortPayload[]) => void;