@danxbot/ui 3.7.0 → 3.8.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.
@@ -0,0 +1,96 @@
1
+ import type { RecordPayload } from "./types";
2
+ /** A relation, once normalized: a pointer to another record's key. */
3
+ export interface RecordRef {
4
+ readonly __ref: string;
5
+ }
6
+ export declare function isRecordRef(value: unknown): value is RecordRef;
7
+ /**
8
+ * Strip a trailing `Resource` so a delete and the record it deletes land on
9
+ * the same key.
10
+ *
11
+ * CREATED AND DELETED PAYLOADS DISAGREE ABOUT `__type`, verified in the
12
+ * backend twice: created/updated take it from a resource class name that no
13
+ * resource overrides, so it keeps the suffix (`"WorkflowRunResource"`), while
14
+ * deletes take it from a helper that strips the suffix (`"WorkflowRun"`).
15
+ *
16
+ * A store keyed on the raw string files a delete under a different key than
17
+ * the record it is deleting, so the tombstone never lands and the row stays on
18
+ * screen forever. One line, and without it a whole class of update silently
19
+ * does nothing.
20
+ */
21
+ export declare function normalizeTypeName(raw: string): string;
22
+ /**
23
+ * `Type:id`, with the id COERCED TO A STRING.
24
+ *
25
+ * Ids are not uniformly numeric — a file's id is a UUID while a run's is an
26
+ * integer — and a Map keyed on the raw value would file `7` and `"7"`
27
+ * separately. There is deliberately NO `id || name` fallback: that is a quirk
28
+ * of one prior implementation, not part of any contract, and a record keyed on
29
+ * a name silently merges two different rows the day two of them share one.
30
+ */
31
+ export declare function recordKey(type: string, id: string | number): string;
32
+ /** The identity a payload carries, or `undefined` if it is not a record. */
33
+ export interface PayloadIdentity {
34
+ readonly key: string;
35
+ readonly type: string;
36
+ readonly id: string;
37
+ }
38
+ export declare function payloadIdentity(payload: RecordPayload): PayloadIdentity | undefined;
39
+ /**
40
+ * A `{__stale:true, id, __model}` ping: an invalidation the backend sends
41
+ * under the normal event name with NO `__type` at all.
42
+ *
43
+ * Recognised by name and dropped, because keying it would need a type it does
44
+ * not have — and guessing one from `__model` (a PHP class name) is exactly the
45
+ * sort of inference that produces a store full of records nothing reads.
46
+ */
47
+ export declare function isStalePing(payload: RecordPayload): boolean;
48
+ /**
49
+ * The tombstone marker, or `undefined`.
50
+ *
51
+ * BOTH SPELLINGS, deliberately. A `deleted` event carries `deleted_at`; a
52
+ * soft-delete arriving as an `updated` event carries `__deleted_at`. The prior
53
+ * art in this codebase checks only the second, so its delete handling has never
54
+ * run once — the payload says `deleted_at` and the store asks for
55
+ * `__deleted_at`.
56
+ */
57
+ export declare function tombstoneAt(payload: RecordPayload): string | undefined;
58
+ /**
59
+ * True when the payload says, in so many words, that the record is NOT
60
+ * deleted — which is what un-deletes a tombstoned record.
61
+ *
62
+ * Needed because absent keeps the previous value: without this, a record that
63
+ * was tombstoned could never come back, even when the server says it has.
64
+ */
65
+ export declare function explicitlyUndeleted(payload: RecordPayload): boolean;
66
+ /**
67
+ * Normalize `__timestamp` to milliseconds.
68
+ *
69
+ * IT ARRIVES IN TWO UNITS, 1000x APART, and this is verified rather than
70
+ * theoretical: the backend reads the model's `updated_at` in MILLISECONDS when
71
+ * the model has that column, and falls back to a SECONDS-resolution wall clock
72
+ * when it does not. At least one real model has no `updated_at` column at all.
73
+ *
74
+ * A comparison across the two units is not merely wrong, it is CONSISTENTLY
75
+ * wrong in one direction: a seconds value is ~1000x smaller, so it always
76
+ * loses to a milliseconds value and such a record would never update again.
77
+ *
78
+ * An implausible magnitude — below either window — is a contract violation,
79
+ * and it is surfaced rather than coerced. It returns `undefined`, which means
80
+ * "cannot adjudicate": the write is still ACCEPTED (a bogus tiny number must
81
+ * not be allowed to make a record permanently un-writable), it just cannot
82
+ * refuse anything.
83
+ */
84
+ export declare function normalizeTimestamp(raw: unknown): number | undefined;
85
+ /**
86
+ * Keys the store INTERPRETS rather than stores.
87
+ *
88
+ * Everything `__`-prefixed is envelope by this wire format's own convention,
89
+ * and two of them would actively break the store if kept as data:
90
+ * `__broadcasted_at` moves on every delivery, so storing it would make an
91
+ * identical redelivered payload look like a change and re-render the world —
92
+ * which is the exact cost the notify-only-if-changed rule exists to avoid.
93
+ *
94
+ * `deleted_at` is here because it is the tombstone marker, not a field.
95
+ */
96
+ export declare function isEnvelopeKey(key: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/ui",
3
- "version": "3.7.0",
3
+ "version": "3.8.0",
4
4
  "type": "module",
5
5
  "description": "Danxbot — a domain-agnostic React design system with motion as a first-class primitive.",
6
6
  "license": "MIT",