@datakable/react 0.0.0-stage → 1.0.1
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/LICENSE +21 -0
- package/README.md +128 -2
- package/dist/codes.cjs +65 -0
- package/dist/codes.cjs.map +1 -0
- package/dist/codes.js +40 -0
- package/dist/codes.js.map +1 -0
- package/dist/data-table.cjs +428 -0
- package/dist/data-table.cjs.map +1 -0
- package/dist/data-table.js +423 -0
- package/dist/data-table.js.map +1 -0
- package/dist/index.cjs +49 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +242 -0
- package/dist/index.d.ts +242 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/render-codes.cjs +77 -0
- package/dist/render-codes.cjs.map +1 -0
- package/dist/render-codes.js +52 -0
- package/dist/render-codes.js.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/use-data-table.cjs +383 -0
- package/dist/use-data-table.cjs.map +1 -0
- package/dist/use-data-table.js +376 -0
- package/dist/use-data-table.js.map +1 -0
- package/package.json +57 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/render-codes.ts"],"sourcesContent":["import {\n type DiagnosticMessages,\n defineDiagnostic,\n defineSlot,\n registerOperation,\n} from '@datakable/core'\n\ndeclare module '@datakable/core' {\n interface DiagnosticCatalog {\n DK_RENDER_FAILED: {\n /**\n * The render operation: `render:cell` (a cell's boundary: a component returned by `cell` /\n * `invalidCell`) or `render:table` (the body boundary: a component outside the cells).\n */\n op: 'render:table' | 'render:cell'\n /** `render:cell`: the slot whose component threw, `columns[1].cell`. */\n slot?: string\n /** `render:cell`: the column id. */\n column?: string\n /** `render:cell`: the row's index in the data (the first failure; later ones are deduped). */\n row?: number\n /** `error.name` only; the full error is `context.cause`. */\n errorName?: string\n }\n }\n\n /** §3.4: React error boundaries, not interceptor chains (nothing runs interceptors on them). */\n interface Operations {\n 'render:table': { kind: 'sync'; input: undefined; output: undefined }\n 'render:cell': {\n kind: 'sync'\n input: { column: string; slot: 'cell' | 'invalidCell'; row: number }\n output: undefined\n }\n }\n}\n\n/**\n * Registers `render:table` / `render:cell` (§3.4: owned by `@datakable/react`, not core). Neither\n * is hot: no interceptor chain runs per cell, so `on: '*'` interceptors get no hot-op warning for\n * them. Idempotent (an identical re-registration is a no-op).\n */\nexport function registerRenderOperations(): void {\n registerOperation('render:table', { kind: 'sync', hot: false })\n registerOperation('render:cell', { kind: 'sync', hot: false })\n}\n\n// No @types/node here: declare just what is read.\ndeclare const process: { env: { NODE_ENV?: string } }\n\n/**\n * `columns[i].cell` (§4.1, §10): renders a React node synchronously. A thenable is a contract\n * violation (`DK_CALLBACK_BAD_RETURN`); `<DataTable />` renders `⚠` instead.\n */\nexport const cellSlot = defineSlot({\n name: 'cell',\n returns: 'sync',\n fallback: 'those cells rendered ⚠',\n})\n\n/** `columns[i].invalidCell` (§5.1): renders a flagged cell; same contract as `cell`. */\nexport const invalidCellSlot = defineSlot({\n name: 'invalidCell',\n returns: 'sync',\n fallback: 'those cells rendered ⚠',\n})\n\n/** Message text (§8.2): development builds, or production via `datakable/messages`. */\nexport const renderMessages: DiagnosticMessages<'DK_RENDER_FAILED'> = {\n DK_RENDER_FAILED: {\n problem: (d) =>\n d.op === 'render:cell'\n ? `a component returned by ${d.slot} (column \"${d.column}\") threw` +\n `${d.errorName ? ` ${d.errorName}` : ''} while rendering row #${d.row}`\n : `a component rendered inside the table body threw${d.errorName ? ` ${d.errorName}` : ''} ` +\n '(outside the cells: a components.Empty / Loading / Error part)',\n impact: (d) =>\n d.op === 'render:cell'\n ? 'that cell renders ⚠; the other cells and rows, the header, search, pagination and the ' +\n \"table API keep working, and the cell renders again when its row's data or the columns \" +\n 'change'\n : 'the table body shows the Error state; the header, search and pagination keep working, ' +\n 'and the body renders again on the next row model or Retry',\n fix: (d) =>\n d.op === 'render:cell'\n ? [\n `find the throwing component in context.cause (passed to onDiagnostic) and make it ` +\n `total: guard null / undefined / unexpected values of column \"${d.column}\" ` +\n 'instead of throwing',\n 'for your own fallback instead of ⚠, wrap the component in an error boundary inside ' +\n `${d.slot}`,\n ]\n : [\n 'find the throwing component in context.cause (passed to onDiagnostic) and make it ' +\n 'total: guard null / undefined / unexpected values instead of throwing',\n 'a component returned by a column cell / invalidCell is caught per cell (⚠); a throw in ' +\n 'the cell function itself is DK_CALLBACK_FAILED',\n ],\n },\n}\n\n/** Codes owned by `<DataTable />` (§8.3, react). Emitted in production too; text behind NODE_ENV. */\nexport const renderDiagnostics = [\n defineDiagnostic(\n {\n code: 'DK_RENDER_FAILED',\n level: 'error',\n where: (d) =>\n d.slot ? { kind: 'operation', op: d.op, slot: d.slot } : { kind: 'operation', op: d.op },\n },\n // Written out (not an imported flag) so a consumer's bundler folds it while parsing (§8.2).\n process.env.NODE_ENV !== 'production' && renderMessages.DK_RENDER_FAILED,\n ),\n]\n"],"mappings":";AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAqCA,SAAS,2BAAiC;AAC/C,oBAAkB,gBAAgB,EAAE,MAAM,QAAQ,KAAK,MAAM,CAAC;AAC9D,oBAAkB,eAAe,EAAE,MAAM,QAAQ,KAAK,MAAM,CAAC;AAC/D;AASO,IAAM,WAAW,WAAW;AAAA,EACjC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AACZ,CAAC;AAGM,IAAM,kBAAkB,WAAW;AAAA,EACxC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU;AACZ,CAAC;AAGM,IAAM,iBAAyD;AAAA,EACpE,kBAAkB;AAAA,IAChB,SAAS,CAAC,MACR,EAAE,OAAO,gBACL,2BAA2B,EAAE,IAAI,aAAa,EAAE,MAAM,WACnD,EAAE,YAAY,IAAI,EAAE,SAAS,KAAK,EAAE,yBAAyB,EAAE,GAAG,KACrE,mDAAmD,EAAE,YAAY,IAAI,EAAE,SAAS,KAAK,EAAE;AAAA,IAE7F,QAAQ,CAAC,MACP,EAAE,OAAO,gBACL,4LAGA;AAAA,IAEN,KAAK,CAAC,MACJ,EAAE,OAAO,gBACL;AAAA,MACE,kJACkE,EAAE,MAAM;AAAA,MAE1E,2FACK,EAAE,IAAI;AAAA,IACb,IACA;AAAA,MACE;AAAA,MAEA;AAAA,IAEF;AAAA,EACR;AACF;AAGO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,MACP,OAAO,CAAC,MACN,EAAE,OAAO,EAAE,MAAM,aAAa,IAAI,EAAE,IAAI,MAAM,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,IAAI,EAAE,GAAG;AAAA,IAC3F;AAAA;AAAA,IAEA,QAAQ,IAAI,aAAa,gBAAgB,eAAe;AAAA,EAC1D;AACF;","names":[]}
|
package/dist/styles.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:where([data-datakable]){--dk-font-size: .875rem;--dk-fg: #1f2328;--dk-muted: #59636e;--dk-bg: #fff;--dk-subtle: #f6f8fa;--dk-border: #d1d9e0;--dk-accent: #0969da;--dk-danger: #d1242f;--dk-danger-bg: #ffebe9;--dk-radius: 6px;--dk-cell-py: .5rem;--dk-cell-px: .75rem;font-size:var(--dk-font-size);color:var(--dk-fg);background:var(--dk-bg);font-variant-numeric:tabular-nums}@media(prefers-color-scheme:dark){:where([data-datakable]){--dk-fg: #f0f6fc;--dk-muted: #9198a1;--dk-bg: #0d1117;--dk-subtle: #151b23;--dk-border: #3d444d;--dk-accent: #4493f8;--dk-danger: #f85149;--dk-danger-bg: #25171c}}:where([data-datakable] table){width:100%;border-collapse:collapse}:where([data-datakable] caption){padding:var(--dk-cell-py) var(--dk-cell-px);color:var(--dk-muted);text-align:start}:where([data-datakable] th,[data-datakable] td){padding:var(--dk-cell-py) var(--dk-cell-px);border-bottom:1px solid var(--dk-border);text-align:start}:where([data-datakable] thead th){background:var(--dk-subtle);font-weight:600;white-space:nowrap}:where([data-datakable] tbody tr:hover){background:var(--dk-subtle)}:where([data-datakable] button){font:inherit;color:inherit;padding:.25rem .625rem;background:var(--dk-bg);border:1px solid var(--dk-border);border-radius:var(--dk-radius);cursor:pointer}:where([data-datakable] button:disabled){opacity:.5;cursor:not-allowed}:where([data-datakable] button:focus-visible,[data-datakable] input:focus-visible){outline:2px solid var(--dk-accent);outline-offset:1px}:where([data-datakable] th[aria-sort] button){font-weight:inherit;padding:0;background:none;border:0}:where([data-datakable] th[aria-sort=ascending],[data-datakable] th[aria-sort=descending]){color:var(--dk-accent)}:where([data-datakable] [data-dk-sort-indicator]){font-size:.75em}:where([data-datakable] [data-dk-search]){display:flex;align-items:center;gap:.5rem;margin-bottom:.5rem}:where([data-datakable] [data-dk-search] input){font:inherit;color:inherit;min-width:12rem;padding:.375rem .625rem;background:var(--dk-bg);border:1px solid var(--dk-border);border-radius:var(--dk-radius)}:where([data-datakable] [data-dk-spinner]){width:1em;height:1em;border:2px solid var(--dk-border);border-top-color:var(--dk-accent);border-radius:50%;animation:dk-spin .7s linear infinite}@keyframes dk-spin{to{transform:rotate(1turn)}}:where([data-datakable] [data-dk-state] td){padding:2rem var(--dk-cell-px);color:var(--dk-muted);text-align:center}:where([data-datakable] tr[data-dk-state]:hover){background:none}:where([data-datakable] [data-dk-state=loading] td){font-style:italic}:where([data-datakable] [data-dk-state=error] td){color:var(--dk-danger)}:where([data-datakable] [data-dk-refresh]){margin-bottom:.5rem;color:var(--dk-muted)}:where([data-datakable] [data-dk-refresh][data-status=error]){padding:.375rem var(--dk-cell-px);color:var(--dk-danger);background:var(--dk-danger-bg);border-radius:var(--dk-radius)}:where([data-datakable][aria-busy=true]:not([data-initial-load=true]) tbody){opacity:.6;transition:opacity .15s}:where([data-datakable] tr[data-invalid=true]){background:var(--dk-danger-bg)}:where([data-datakable] td[data-invalid=true]){color:var(--dk-danger);box-shadow:inset 2px 0 var(--dk-danger)}:where([data-datakable] [data-dk-invalid-marker]){color:var(--dk-danger)}:where([data-datakable] [data-dk-pagination]){display:flex;align-items:center;justify-content:flex-end;gap:.5rem;margin-top:.5rem}:where([data-datakable] [data-dk-page]){color:var(--dk-muted)}@media(prefers-reduced-motion:reduce){:where([data-datakable] [data-dk-spinner]){animation:none;border-color:var(--dk-accent)}:where([data-datakable] *){transition:none}}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/use-data-table.ts
|
|
22
|
+
var use_data_table_exports = {};
|
|
23
|
+
__export(use_data_table_exports, {
|
|
24
|
+
useDataTable: () => useDataTable
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(use_data_table_exports);
|
|
27
|
+
var import_core = require("@datakable/core");
|
|
28
|
+
var import_react = require("react");
|
|
29
|
+
|
|
30
|
+
// package.json
|
|
31
|
+
var version = "1.0.1";
|
|
32
|
+
|
|
33
|
+
// src/use-data-table.ts
|
|
34
|
+
var import_codes = require("./codes.cjs");
|
|
35
|
+
(0, import_core.keepDiagnostics)(import_codes.reactDiagnostics);
|
|
36
|
+
var useIsomorphicLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
|
|
37
|
+
var SYNCED = [
|
|
38
|
+
"data",
|
|
39
|
+
"columns",
|
|
40
|
+
"rowKey",
|
|
41
|
+
"state",
|
|
42
|
+
"onStateChange",
|
|
43
|
+
"interceptors",
|
|
44
|
+
"onDiagnostic",
|
|
45
|
+
"fetcher",
|
|
46
|
+
"rowCount"
|
|
47
|
+
];
|
|
48
|
+
var CALLBACKS = ["onStateChange", "onDiagnostic", "fetcher"];
|
|
49
|
+
var UNSTABLE_AFTER = 2;
|
|
50
|
+
var registered = false;
|
|
51
|
+
function useDataTable(options) {
|
|
52
|
+
const ref = (0, import_react.useRef)(null);
|
|
53
|
+
if (ref.current === null) ref.current = createInstance(options);
|
|
54
|
+
const inst = ref.current;
|
|
55
|
+
const table = inst.table;
|
|
56
|
+
const [, rerender] = (0, import_react.useReducer)((n) => n + 1, 0);
|
|
57
|
+
const subscribe = (0, import_react.useCallback)(
|
|
58
|
+
(onChange) => {
|
|
59
|
+
if (inst.table !== table || inst.destroyed) return () => {
|
|
60
|
+
};
|
|
61
|
+
return table.subscribe(() => {
|
|
62
|
+
inst.version++;
|
|
63
|
+
if (inst.syncing) inst.selfCaused = true;
|
|
64
|
+
onChange();
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
[inst, table]
|
|
68
|
+
);
|
|
69
|
+
const getSnapshot = (0, import_react.useCallback)(() => snapshot(inst, table), [inst, table]);
|
|
70
|
+
const getServerSnapshot = (0, import_react.useCallback)(() => serverSnapshot(inst, table), [inst, table]);
|
|
71
|
+
const view = (0, import_react.useSyncExternalStore)(subscribe, getSnapshot, getServerSnapshot);
|
|
72
|
+
(0, import_react.useInsertionEffect)(() => checkHydration(inst), [inst]);
|
|
73
|
+
useIsomorphicLayoutEffect(() => {
|
|
74
|
+
inst.mounted = true;
|
|
75
|
+
if (inst.destroyed) {
|
|
76
|
+
recreate(inst);
|
|
77
|
+
(0, import_core.startTable)(inst.table);
|
|
78
|
+
rerender();
|
|
79
|
+
} else {
|
|
80
|
+
(0, import_core.startTable)(inst.table);
|
|
81
|
+
if (snapshot(inst, inst.table) !== view) rerender();
|
|
82
|
+
}
|
|
83
|
+
return () => {
|
|
84
|
+
inst.mounted = false;
|
|
85
|
+
queueMicrotask(() => {
|
|
86
|
+
if (inst.mounted || inst.destroyed) return;
|
|
87
|
+
inst.destroyed = true;
|
|
88
|
+
inst.table.destroy();
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
}, [inst]);
|
|
92
|
+
useIsomorphicLayoutEffect(() => {
|
|
93
|
+
inst.latest = options;
|
|
94
|
+
const selfCaused = inst.selfCaused;
|
|
95
|
+
inst.selfCaused = false;
|
|
96
|
+
if (!inst.destroyed) sync(inst, options, selfCaused);
|
|
97
|
+
deliver(inst);
|
|
98
|
+
});
|
|
99
|
+
return view;
|
|
100
|
+
}
|
|
101
|
+
function createInstance(options) {
|
|
102
|
+
const inst = {
|
|
103
|
+
table: void 0,
|
|
104
|
+
destroyed: false,
|
|
105
|
+
mounted: false,
|
|
106
|
+
latest: options,
|
|
107
|
+
synced: options,
|
|
108
|
+
wrappers: {
|
|
109
|
+
onStateChange: (updater) => inst.latest.onStateChange(updater),
|
|
110
|
+
onDiagnostic: (d) => {
|
|
111
|
+
if (inst.rendering === 0) {
|
|
112
|
+
;
|
|
113
|
+
inst.latest.onDiagnostic?.(d);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (inst.queue === void 0) {
|
|
117
|
+
inst.queue = [];
|
|
118
|
+
queueMicrotask(() => deliver(inst));
|
|
119
|
+
}
|
|
120
|
+
inst.queue.push(d);
|
|
121
|
+
},
|
|
122
|
+
fetcher: (params) => inst.latest.fetcher(params)
|
|
123
|
+
},
|
|
124
|
+
queue: void 0,
|
|
125
|
+
rendering: 0,
|
|
126
|
+
syncing: false,
|
|
127
|
+
selfCaused: false,
|
|
128
|
+
selfData: false,
|
|
129
|
+
version: 0,
|
|
130
|
+
view: void 0,
|
|
131
|
+
server: void 0,
|
|
132
|
+
hydrating: false,
|
|
133
|
+
seen: options,
|
|
134
|
+
unstable: /* @__PURE__ */ new Map(),
|
|
135
|
+
warned: /* @__PURE__ */ new Set()
|
|
136
|
+
};
|
|
137
|
+
if (process.env.NODE_ENV !== "production" && !registered) {
|
|
138
|
+
registered = true;
|
|
139
|
+
(0, import_core.registerPackage)("@datakable/react", version);
|
|
140
|
+
}
|
|
141
|
+
build(inst, options);
|
|
142
|
+
return inst;
|
|
143
|
+
}
|
|
144
|
+
function wrapper(inst, k, v) {
|
|
145
|
+
const w = inst.wrappers[k];
|
|
146
|
+
if (k === "fetcher") {
|
|
147
|
+
;
|
|
148
|
+
w[import_core.SERVER_SOURCE] = v[import_core.SERVER_SOURCE];
|
|
149
|
+
}
|
|
150
|
+
return w;
|
|
151
|
+
}
|
|
152
|
+
function build(inst, options) {
|
|
153
|
+
const init = { ...options };
|
|
154
|
+
for (const k of CALLBACKS) {
|
|
155
|
+
if (typeof options[k] === "function") init[k] = wrapper(inst, k, options[k]);
|
|
156
|
+
}
|
|
157
|
+
inst.rendering++;
|
|
158
|
+
try {
|
|
159
|
+
inst.table = (0, import_core.createDeferred)(() => (0, import_core.createTable)(init));
|
|
160
|
+
} finally {
|
|
161
|
+
inst.rendering--;
|
|
162
|
+
}
|
|
163
|
+
inst.synced = options;
|
|
164
|
+
inst.seen = options;
|
|
165
|
+
inst.view = void 0;
|
|
166
|
+
inst.server = void 0;
|
|
167
|
+
}
|
|
168
|
+
function recreate(inst) {
|
|
169
|
+
build(inst, inst.latest);
|
|
170
|
+
inst.destroyed = false;
|
|
171
|
+
}
|
|
172
|
+
function snapshot(inst, table) {
|
|
173
|
+
inst.rendering++;
|
|
174
|
+
try {
|
|
175
|
+
const state = table.getState();
|
|
176
|
+
const rowModel = table.getRowModel();
|
|
177
|
+
const v = inst.view;
|
|
178
|
+
if (v && v.table === table && v.version === inst.version) {
|
|
179
|
+
const value2 = v.value;
|
|
180
|
+
if (value2.state === state && value2.rowModel === rowModel) return value2;
|
|
181
|
+
}
|
|
182
|
+
const value = Object.create(table, {
|
|
183
|
+
state: { value: state, enumerable: true },
|
|
184
|
+
rowModel: { value: rowModel, enumerable: true }
|
|
185
|
+
});
|
|
186
|
+
inst.view = { table, version: inst.version, value };
|
|
187
|
+
return value;
|
|
188
|
+
} finally {
|
|
189
|
+
inst.rendering--;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function serverSnapshot(inst, table) {
|
|
193
|
+
if (inst.table !== table) return snapshot(inst, table);
|
|
194
|
+
if (typeof window !== "undefined") inst.hydrating = true;
|
|
195
|
+
const s = inst.server;
|
|
196
|
+
if (s && s.table === table) return s.value;
|
|
197
|
+
const value = snapshot(inst, table);
|
|
198
|
+
inst.server = { table, value };
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
function checkHydration(inst) {
|
|
202
|
+
if (!inst.hydrating) return;
|
|
203
|
+
inst.hydrating = false;
|
|
204
|
+
const server = inst.server;
|
|
205
|
+
if (!server || server.table !== inst.table) return;
|
|
206
|
+
const live = snapshot(inst, inst.table);
|
|
207
|
+
const hydrated = server.value;
|
|
208
|
+
if (live === hydrated) return;
|
|
209
|
+
const slices = [];
|
|
210
|
+
for (const k of /* @__PURE__ */ new Set([...Object.keys(hydrated.state), ...Object.keys(live.state)])) {
|
|
211
|
+
if (!Object.is(hydrated.state[k], live.state[k])) slices.push(k);
|
|
212
|
+
}
|
|
213
|
+
if (slices.length === 0) {
|
|
214
|
+
if (live.rowModel === hydrated.rowModel) return;
|
|
215
|
+
slices.push("rows");
|
|
216
|
+
}
|
|
217
|
+
inst.rendering++;
|
|
218
|
+
try {
|
|
219
|
+
(0, import_core.emitTableDiagnostic)(
|
|
220
|
+
inst.table,
|
|
221
|
+
"DK_HYDRATION_MISMATCH",
|
|
222
|
+
{ slices },
|
|
223
|
+
{ trigger: "hydrate", phase: "hydrate" }
|
|
224
|
+
);
|
|
225
|
+
} finally {
|
|
226
|
+
inst.rendering--;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function sync(inst, options, selfCaused) {
|
|
230
|
+
if (process.env.NODE_ENV !== "production") checkUnstable(inst, options);
|
|
231
|
+
const prev = inst.synced;
|
|
232
|
+
if (!selfCaused) inst.selfData = false;
|
|
233
|
+
let partial;
|
|
234
|
+
for (const k of SYNCED) {
|
|
235
|
+
const v = options[k];
|
|
236
|
+
const p = prev[k];
|
|
237
|
+
if (Object.is(v, p)) continue;
|
|
238
|
+
let forward = v;
|
|
239
|
+
switch (k) {
|
|
240
|
+
case "onStateChange":
|
|
241
|
+
case "onDiagnostic":
|
|
242
|
+
case "fetcher": {
|
|
243
|
+
const on = typeof v === "function";
|
|
244
|
+
if (on === (typeof p === "function")) continue;
|
|
245
|
+
forward = on ? wrapper(inst, k, v) : void 0;
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case "state":
|
|
249
|
+
if (sameSlices(v, p)) continue;
|
|
250
|
+
break;
|
|
251
|
+
case "interceptors":
|
|
252
|
+
if (sameItems(v, p)) continue;
|
|
253
|
+
break;
|
|
254
|
+
case "data":
|
|
255
|
+
if (isEmpty(v) && sameItems(v, p)) continue;
|
|
256
|
+
if (selfCaused) {
|
|
257
|
+
if (inst.selfData || sameRows(v, p)) continue;
|
|
258
|
+
inst.selfData = true;
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
case "columns":
|
|
262
|
+
if (selfCaused && sameShape(v, p)) continue;
|
|
263
|
+
break;
|
|
264
|
+
case "rowKey":
|
|
265
|
+
if (selfCaused && typeof v === "function" && typeof p === "function") continue;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
partial ??= {};
|
|
269
|
+
partial[k] = forward;
|
|
270
|
+
}
|
|
271
|
+
if (partial === void 0) return;
|
|
272
|
+
inst.syncing = true;
|
|
273
|
+
try {
|
|
274
|
+
inst.table.setOptions(partial);
|
|
275
|
+
} finally {
|
|
276
|
+
inst.syncing = false;
|
|
277
|
+
}
|
|
278
|
+
const synced = { ...prev };
|
|
279
|
+
for (const k of Object.keys(partial)) synced[k] = options[k];
|
|
280
|
+
inst.synced = synced;
|
|
281
|
+
}
|
|
282
|
+
function deliver(inst) {
|
|
283
|
+
const queue = inst.queue;
|
|
284
|
+
if (queue === void 0) return;
|
|
285
|
+
inst.queue = void 0;
|
|
286
|
+
const sink = inst.latest.onDiagnostic;
|
|
287
|
+
for (const d of queue) {
|
|
288
|
+
try {
|
|
289
|
+
sink?.(d);
|
|
290
|
+
} catch (e) {
|
|
291
|
+
console.error("[DataKable] onDiagnostic threw", e);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
var isObject = (v) => v !== null && typeof v === "object";
|
|
296
|
+
function sameSlices(a, b) {
|
|
297
|
+
if (!isObject(a) || !isObject(b)) return false;
|
|
298
|
+
const defined = (o) => Object.keys(o).filter((k) => o[k] !== void 0);
|
|
299
|
+
const keys = defined(a);
|
|
300
|
+
if (keys.length !== defined(b).length) return false;
|
|
301
|
+
for (const k of keys) if (!Object.is(a[k], b[k])) return false;
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
var isEmpty = (v) => Array.isArray(v) && v.length === 0;
|
|
305
|
+
function sameItems(a, b) {
|
|
306
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
307
|
+
for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
function sameRows(a, b) {
|
|
311
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
312
|
+
for (let i = 0; i < a.length; i++) {
|
|
313
|
+
const x = a[i];
|
|
314
|
+
const y = b[i];
|
|
315
|
+
if (Object.is(x, y)) continue;
|
|
316
|
+
if (!isObject(x) || !isObject(y)) return false;
|
|
317
|
+
const keys = Object.keys(x);
|
|
318
|
+
if (keys.length !== Object.keys(y).length) return false;
|
|
319
|
+
for (const k of keys) if (!Object.hasOwn(y, k) || !Object.is(x[k], y[k])) return false;
|
|
320
|
+
}
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
var loose = (v) => typeof v === "function" || isObject(v);
|
|
324
|
+
function sameShape(a, b) {
|
|
325
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
326
|
+
for (let i = 0; i < a.length; i++) {
|
|
327
|
+
const x = a[i];
|
|
328
|
+
const y = b[i];
|
|
329
|
+
if (Object.is(x, y)) continue;
|
|
330
|
+
if (!isObject(x) || !isObject(y)) return false;
|
|
331
|
+
const keys = Object.keys(x);
|
|
332
|
+
if (keys.length !== Object.keys(y).length) return false;
|
|
333
|
+
for (const k of keys) {
|
|
334
|
+
if (!Object.hasOwn(y, k)) return false;
|
|
335
|
+
const vx = x[k];
|
|
336
|
+
const vy = y[k];
|
|
337
|
+
if (Object.is(vx, vy)) continue;
|
|
338
|
+
if (!(loose(vx) && loose(vy) && typeof vx === typeof vy)) return false;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
function changedFeatureOption(a, b) {
|
|
344
|
+
if (!Array.isArray(a) || !Array.isArray(b) || a === b) return void 0;
|
|
345
|
+
for (let i = 0; i < a.length; i++) {
|
|
346
|
+
const f = a[i];
|
|
347
|
+
const g = b[i];
|
|
348
|
+
if (!f || !g || f === g || f.name !== g.name) continue;
|
|
349
|
+
if (!(0, import_core.isOptionsDefinition)(f.options) || !(0, import_core.isOptionsDefinition)(g.options)) continue;
|
|
350
|
+
const fv = f.options.values;
|
|
351
|
+
const gv = g.options.values;
|
|
352
|
+
if (!fv || !gv) continue;
|
|
353
|
+
for (const k of Object.keys(fv)) {
|
|
354
|
+
if (typeof fv[k] === "function" && fv[k] !== gv[k]) return `features[${i}].${k}`;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return void 0;
|
|
358
|
+
}
|
|
359
|
+
function checkUnstable(inst, options) {
|
|
360
|
+
const seen = inst.seen;
|
|
361
|
+
inst.seen = options;
|
|
362
|
+
const changed = (k) => !Object.is(options[k], seen[k]);
|
|
363
|
+
const fn = (k) => changed(k) && typeof options[k] === "function" && typeof seen[k] === "function";
|
|
364
|
+
track(inst, "columns", changed("columns") && sameShape(options.columns, seen.columns));
|
|
365
|
+
track(inst, "data", changed("data") && sameRows(options.data, seen.data));
|
|
366
|
+
track(inst, "fetcher", fn("fetcher"));
|
|
367
|
+
track(inst, "rowKey", fn("rowKey"));
|
|
368
|
+
const option = changedFeatureOption(options.features, seen.features);
|
|
369
|
+
track(inst, "features", option !== void 0, option);
|
|
370
|
+
}
|
|
371
|
+
function track(inst, key, unstable, option = key) {
|
|
372
|
+
const n = unstable ? (inst.unstable.get(key) ?? 0) + 1 : 0;
|
|
373
|
+
inst.unstable.set(key, n);
|
|
374
|
+
if (n < UNSTABLE_AFTER || inst.warned.has(key)) return;
|
|
375
|
+
inst.warned.add(key);
|
|
376
|
+
if (key === "columns") (0, import_core.emitTableDiagnostic)(inst.table, "DK_UNSTABLE_COLUMNS", { renders: n });
|
|
377
|
+
else (0, import_core.emitTableDiagnostic)(inst.table, "DK_UNSTABLE_OPTION", { option, renders: n });
|
|
378
|
+
}
|
|
379
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
380
|
+
0 && (module.exports = {
|
|
381
|
+
useDataTable
|
|
382
|
+
});
|
|
383
|
+
//# sourceMappingURL=use-data-table.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/use-data-table.ts","../package.json"],"sourcesContent":["'use client'\n\nimport {\n type AnyFeature,\n type ApiOf,\n type ColumnDef,\n type CreateTableOptions,\n createDeferred,\n createTable,\n type Diagnostic,\n emitTableDiagnostic,\n type InvalidRowsMode,\n isOptionsDefinition,\n keepDiagnostics,\n type RowModel,\n registerPackage,\n type SchemaRow,\n SERVER_SOURCE,\n startTable,\n type Table,\n type TableSchema,\n type TableState,\n type TableStateFor,\n} from '@datakable/core'\nimport {\n type ReactNode,\n useCallback,\n useEffect,\n useInsertionEffect,\n useLayoutEffect,\n useReducer,\n useRef,\n useSyncExternalStore,\n} from 'react'\nimport { version } from '../package.json'\nimport { reactDiagnostics } from './codes'\n\n// Registers the (development-only) definitions where they are emitted, so bundlers keep them.\nkeepDiagnostics(reactDiagnostics)\n\n// No @types/node here: declare just what is read.\ndeclare const process: { env: { NODE_ENV?: string } }\n\n/** No layout effects on the server (React 18 warns about them there). */\nconst useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect\n\n/**\n * `useDataTable` options: `createTable`'s (§3.2), with `cell` / `invalidCell` returning a\n * `ReactNode` (§10). Read once, at creation: `features`, `schema`, `invalidRows`, `initialState`,\n * `name`, `timeout`, `strict`, `diagnostics`. Every other option follows the latest render.\n */\nexport type UseDataTableOptions<\n T,\n S extends TableState = TableState,\n Sch = undefined,\n M extends InvalidRowsMode = 'drop',\n> = Omit<CreateTableOptions<T, S, Sch, M>, 'columns'> & {\n /**\n * Compared by reference (§10): a new array tells the table the columns changed. Define them\n * outside the component or memoise them (`DK_UNSTABLE_COLUMNS` in development).\n */\n columns?: readonly ColumnDef<SchemaRow<T, Sch>, ReactNode>[]\n}\n\n/**\n * What `useDataTable` returns: the table (its methods and the installed features' APIs) with the\n * `state` and `rowModel` of this render. A new object whenever the table notifies, so it can be a\n * dependency of `useMemo` / `memo` children; the same object while nothing changed.\n */\nexport type UseDataTableResult<\n T,\n S extends TableState = TableState,\n M extends InvalidRowsMode = 'drop',\n In = T,\n Api = unknown,\n> = Table<T, S, M, In> &\n Api & {\n /** The state snapshot of this render (`getState()`). */\n readonly state: S\n /** The row model of this render (`getRowModel()`, §6.6): rows, counts, status. */\n readonly rowModel: RowModel<T, M>\n }\n\ntype Options = Record<string, unknown> & { features?: readonly AnyFeature[] }\ntype AnyTable = Table<unknown, TableState> & Record<string, unknown>\ntype Callback = (arg: never) => unknown\n\n/** Options forwarded through `setOptions` when they change; the rest are read once (§3.4). */\nconst SYNCED = [\n 'data',\n 'columns',\n 'rowKey',\n 'state',\n 'onStateChange',\n 'interceptors',\n 'onDiagnostic',\n 'fetcher',\n 'rowCount',\n] as const\n\n/** Given to the table as stable wrappers that call the latest prop (latest-ref). */\nconst CALLBACKS = ['onStateChange', 'onDiagnostic', 'fetcher'] as const\ntype CallbackKey = (typeof CALLBACKS)[number]\n\n/** Renders in a row with a new reference before `DK_UNSTABLE_*` is reported. */\nconst UNSTABLE_AFTER = 2\n\ninterface Instance {\n table: AnyTable\n destroyed: boolean\n mounted: boolean\n /** The options of the latest committed render (what the wrappers call). */\n latest: Options\n /** The option values the table has (user values; callbacks count by presence). */\n synced: Options\n readonly wrappers: Record<CallbackKey, Callback>\n /** `onDiagnostic` calls made while rendering, delivered after the commit. */\n queue: Diagnostic[] | undefined\n rendering: number\n /** Inside the hook's own `setOptions` call. */\n syncing: boolean\n /** That call notified: the next commit is the re-render it caused. */\n selfCaused: boolean\n /**\n * `data` was forwarded in a self-caused re-render. Rows that differ on every render (nested\n * objects, computed fields) would otherwise ingest → notify → re-render forever: the next\n * self-caused re-render keeps the data the table has.\n */\n selfData: boolean\n /** Notifications seen; part of the view cache key (a notification is never silent, §6.6). */\n version: number\n view: { table: AnyTable; version: number; value: object } | undefined\n /**\n * SSR (§7.2): the view of `table` at its creation — initial state, controlled state and data /\n * initialData, no async result (the table is created deferred). `getServerSnapshot`.\n */\n server: { table: AnyTable; value: object } | undefined\n /** React read `getServerSnapshot` on the client: this render hydrates server HTML. */\n hydrating: boolean\n // Dev: DK_UNSTABLE_* bookkeeping.\n /** The options of the previous committed render. */\n seen: Options\n unstable: Map<string, number>\n warned: Set<string>\n}\n\nlet registered = false\n\n/**\n * Binds a table to a component (§10): the table is created once per component instance and\n * destroyed on unmount; renders read it through `useSyncExternalStore` (with\n * `getServerSnapshot`), and options are synced with `table.setOptions` in a layout effect, never\n * during render.\n *\n * - `features` (and the other read-once options) are read at creation: a new inline `features`\n * array never recreates the table.\n * - `fetcher`, `onStateChange` and `onDiagnostic` may be inline functions: the table always calls\n * the latest one, and a new reference never refetches (call `refetch()` when a value the fetcher\n * reads changes).\n * - `columns`, `data` and a `rowKey` function are compared by reference: memoise them.\n * - Controlled slices (§3.2): pass `state` and `onStateChange`; changes come back through `state`.\n * - SSR (§7.2): rendering starts no async work. The fetcher's first request and a `searchFn` for an\n * initial query start after the commit (`status: 'pending'` until then; `DK_SSR_ASYNC_DEFERRED`\n * on the server), unless `initialData` already holds their result. `initialState` (e.g. parsed\n * from the URL) applies on the server: client-mode features filter / search / sort the HTML.\n * `getServerSnapshot` is the view at creation; a table that changed before the hydration commit\n * reports `DK_HYDRATION_MISMATCH`.\n *\n * `@datakable/react` installs no features by default; `datakable`'s `useDataTable` installs the\n * default preset.\n */\nexport function useDataTable<\n T,\n S extends TableState = never,\n const Fs extends readonly AnyFeature[] = [],\n const Sch extends TableSchema | undefined = undefined,\n const M extends InvalidRowsMode = 'drop',\n>(\n options: UseDataTableOptions<T, TableStateFor<S, Fs, SchemaRow<T, Sch>>, Sch, M> & {\n features?: Fs\n },\n): UseDataTableResult<\n SchemaRow<T, Sch>,\n TableStateFor<S, Fs, SchemaRow<T, Sch>>,\n M,\n [Sch] extends [TableSchema] ? unknown : T,\n ApiOf<Fs, SchemaRow<T, Sch>>\n>\nexport function useDataTable(options: Options): unknown {\n const ref = useRef<Instance | null>(null)\n // Created during the first render (React keeps the ref across the StrictMode double render),\n // deferred: its async work (fetcher, searchFn) starts in the mount effect, never on the server.\n if (ref.current === null) ref.current = createInstance(options)\n const inst = ref.current\n const table = inst.table\n const [, rerender] = useReducer((n: number) => n + 1, 0)\n\n const subscribe = useCallback(\n (onChange: () => void) => {\n // Replaced or destroyed meanwhile (`<Activity>`): nothing to subscribe to.\n if (inst.table !== table || inst.destroyed) return () => {}\n return table.subscribe(() => {\n inst.version++\n if (inst.syncing) inst.selfCaused = true\n onChange()\n })\n },\n [inst, table],\n )\n const getSnapshot = useCallback(() => snapshot(inst, table), [inst, table])\n const getServerSnapshot = useCallback(() => serverSnapshot(inst, table), [inst, table])\n const view = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n\n // Hydration commit (§7.2): before any layout effect can change the table, the snapshot React\n // hydrated with must still be the live one, else React replaces the server HTML at once.\n useInsertionEffect(() => checkHydration(inst), [inst])\n\n useIsomorphicLayoutEffect(() => {\n inst.mounted = true\n // Destroyed while hidden (`<Activity>`): a new table, from the latest options.\n if (inst.destroyed) {\n recreate(inst)\n startTable(inst.table)\n rerender()\n } else {\n // The deferred fetch / searchFn starts now; its status shows before paint.\n startTable(inst.table)\n if (snapshot(inst, inst.table) !== view) rerender()\n }\n return () => {\n inst.mounted = false\n // Deferred: the StrictMode effect re-run mounts again synchronously and keeps the table.\n queueMicrotask(() => {\n if (inst.mounted || inst.destroyed) return\n inst.destroyed = true\n inst.table.destroy()\n })\n }\n }, [inst])\n\n useIsomorphicLayoutEffect(() => {\n inst.latest = options\n const selfCaused = inst.selfCaused\n inst.selfCaused = false\n if (!inst.destroyed) sync(inst, options, selfCaused)\n deliver(inst)\n })\n\n return view\n}\n\nfunction createInstance(options: Options): Instance {\n const inst: Instance = {\n table: undefined as unknown as AnyTable,\n destroyed: false,\n mounted: false,\n latest: options,\n synced: options,\n wrappers: {\n onStateChange: (updater) => (inst.latest.onStateChange as Callback)(updater),\n onDiagnostic: (d: Diagnostic) => {\n if (inst.rendering === 0) {\n ;(inst.latest.onDiagnostic as ((d: Diagnostic) => void) | undefined)?.(d)\n return\n }\n if (inst.queue === undefined) {\n inst.queue = []\n // Delivered by the next layout effect, or here when this render never commits.\n queueMicrotask(() => deliver(inst))\n }\n inst.queue.push(d)\n },\n fetcher: (params) => (inst.latest.fetcher as Callback)(params),\n },\n queue: undefined,\n rendering: 0,\n syncing: false,\n selfCaused: false,\n selfData: false,\n version: 0,\n view: undefined,\n server: undefined,\n hydrating: false,\n seen: options,\n unstable: new Map(),\n warned: new Set(),\n }\n // The version checks are development-only (§8.5): production bundles no registry.\n if (process.env.NODE_ENV !== 'production' && !registered) {\n registered = true\n registerPackage('@datakable/react', version)\n }\n build(inst, options)\n return inst\n}\n\n/**\n * The stable wrapper of callback `k`. The fetcher's also carries the server source of the user's\n * `withFetcher` fetcher (§7.1), which is what makes the table load through it.\n */\nfunction wrapper(inst: Instance, k: CallbackKey, v: unknown): Callback {\n const w = inst.wrappers[k]\n if (k === 'fetcher') {\n ;(w as unknown as Record<symbol, unknown>)[SERVER_SOURCE] = (v as Record<symbol, unknown>)[\n SERVER_SOURCE\n ]\n }\n return w\n}\n\nfunction build(inst: Instance, options: Options) {\n const init: Options = { ...options }\n for (const k of CALLBACKS) {\n if (typeof options[k] === 'function') init[k] = wrapper(inst, k, options[k])\n }\n inst.rendering++\n try {\n // Deferred (§7.2): rendering starts no fetch / searchFn (none at all on the server, where\n // effects never run); the mount effect starts it.\n inst.table = createDeferred(() => createTable(init as never)) as unknown as AnyTable\n } finally {\n inst.rendering--\n }\n inst.synced = options\n inst.seen = options\n inst.view = undefined\n inst.server = undefined\n}\n\nfunction recreate(inst: Instance) {\n build(inst, inst.latest)\n inst.destroyed = false\n}\n\n/** The view of the table's snapshot, cached on (table, state, row model, notifications). */\nfunction snapshot(inst: Instance, table: AnyTable): object {\n inst.rendering++\n try {\n const state = table.getState()\n const rowModel = table.getRowModel()\n const v = inst.view\n if (v && v.table === table && v.version === inst.version) {\n const value = v.value as { state: unknown; rowModel: unknown }\n if (value.state === state && value.rowModel === rowModel) return value\n }\n const value = Object.create(table, {\n state: { value: state, enumerable: true },\n rowModel: { value: rowModel, enumerable: true },\n }) as object\n inst.view = { table, version: inst.version, value }\n return value\n } finally {\n inst.rendering--\n }\n}\n\n/**\n * `getServerSnapshot` (§7.2): the view of the table at its creation. React reads it on the server\n * and while hydrating, so both render the same snapshot; async work never ran in it.\n */\nfunction serverSnapshot(inst: Instance, table: AnyTable): object {\n if (inst.table !== table) return snapshot(inst, table)\n // On the client React reads it only to hydrate.\n if (typeof window !== 'undefined') inst.hydrating = true\n const s = inst.server\n if (s && s.table === table) return s.value\n const value = snapshot(inst, table)\n inst.server = { table, value }\n return value\n}\n\n/** `DK_HYDRATION_MISMATCH`: what differs between the hydrated (server) view and the live one. */\nfunction checkHydration(inst: Instance) {\n if (!inst.hydrating) return\n inst.hydrating = false\n const server = inst.server\n if (!server || server.table !== inst.table) return\n const live = snapshot(inst, inst.table) as { state: TableState; rowModel: unknown }\n const hydrated = server.value as { state: TableState; rowModel: unknown }\n if (live === hydrated) return\n const slices: string[] = []\n for (const k of new Set([...Object.keys(hydrated.state), ...Object.keys(live.state)])) {\n if (!Object.is(hydrated.state[k], live.state[k])) slices.push(k)\n }\n if (slices.length === 0) {\n if (live.rowModel === hydrated.rowModel) return\n slices.push('rows')\n }\n // Delivered to onDiagnostic by the layout effect (no update during the commit).\n inst.rendering++\n try {\n emitTableDiagnostic(\n inst.table,\n 'DK_HYDRATION_MISMATCH',\n { slices },\n { trigger: 'hydrate', phase: 'hydrate' },\n )\n } finally {\n inst.rendering--\n }\n}\n\n/**\n * Forwards the changed options with one `setOptions` call. In the re-render caused by that call,\n * values recomputed from the same inputs (same-shape `columns`, `data` with equal rows, a `rowKey`\n * function) are not forwarded again: an inline `columns` / `data` would otherwise loop. A `data`\n * that still differs is forwarded at most once per chain of self-caused re-renders, so rows that\n * are new on every render (`data: [{ … }]` with nested objects) re-ingest but never hang.\n */\nfunction sync(inst: Instance, options: Options, selfCaused: boolean) {\n // Written out (not a module-level flag) so bundlers fold it while parsing (§8.2).\n if (process.env.NODE_ENV !== 'production') checkUnstable(inst, options)\n const prev = inst.synced\n if (!selfCaused) inst.selfData = false\n let partial: Record<string, unknown> | undefined\n for (const k of SYNCED) {\n const v = options[k]\n const p = prev[k]\n if (Object.is(v, p)) continue\n let forward: unknown = v\n switch (k) {\n case 'onStateChange':\n case 'onDiagnostic':\n case 'fetcher': {\n const on = typeof v === 'function'\n if (on === (typeof p === 'function')) continue\n forward = on ? wrapper(inst, k, v) : undefined\n break\n }\n case 'state':\n if (sameSlices(v, p)) continue\n break\n case 'interceptors':\n if (sameItems(v, p)) continue\n break\n case 'data':\n // Two empty arrays hold nothing to ingest (e.g. an inline `data: []` with a fetcher).\n if (isEmpty(v) && sameItems(v, p)) continue\n if (selfCaused) {\n if (inst.selfData || sameRows(v, p)) continue\n inst.selfData = true\n }\n break\n case 'columns':\n if (selfCaused && sameShape(v, p)) continue\n break\n case 'rowKey':\n if (selfCaused && typeof v === 'function' && typeof p === 'function') continue\n break\n }\n partial ??= {}\n partial[k] = forward\n }\n if (partial === undefined) return\n inst.syncing = true\n try {\n inst.table.setOptions(partial)\n } finally {\n inst.syncing = false\n }\n const synced = { ...prev }\n for (const k of Object.keys(partial)) synced[k] = options[k]\n inst.synced = synced\n}\n\n/** Delivers the `onDiagnostic` calls queued while rendering. */\nfunction deliver(inst: Instance) {\n const queue = inst.queue\n if (queue === undefined) return\n inst.queue = undefined\n const sink = inst.latest.onDiagnostic as ((d: Diagnostic) => void) | undefined\n for (const d of queue) {\n try {\n sink?.(d)\n } catch (e) {\n // Like a failing sink in the hub: the logger never breaks the table.\n console.error('[DataKable] onDiagnostic threw', e)\n }\n }\n}\n\n// --- comparisons ---------------------------------------------------------------------------------\n\nconst isObject = (v: unknown): v is Record<string, unknown> => v !== null && typeof v === 'object'\n\n/** Controlled slices: the same defined slices, each `Object.is`-equal. */\nfunction sameSlices(a: unknown, b: unknown): boolean {\n if (!isObject(a) || !isObject(b)) return false\n const defined = (o: Record<string, unknown>) => Object.keys(o).filter((k) => o[k] !== undefined)\n const keys = defined(a)\n if (keys.length !== defined(b).length) return false\n for (const k of keys) if (!Object.is(a[k], b[k])) return false\n return true\n}\n\nconst isEmpty = (v: unknown) => Array.isArray(v) && v.length === 0\n\n/** Two arrays with the same items (by reference). */\nfunction sameItems(a: unknown, b: unknown): boolean {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false\n return true\n}\n\n/**\n * Two arrays of equal rows: each pair the same reference, or objects with the same own keys and\n * `Object.is`-equal values (`data: rows.map((r) => ({ ...r }))` recomputed in a re-render).\n */\nfunction sameRows(a: unknown, b: unknown): boolean {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x: unknown = a[i]\n const y: unknown = b[i]\n if (Object.is(x, y)) continue\n if (!isObject(x) || !isObject(y)) return false\n const keys = Object.keys(x)\n if (keys.length !== Object.keys(y).length) return false\n for (const k of keys) if (!Object.hasOwn(y, k) || !Object.is(x[k], y[k])) return false\n }\n return true\n}\n\nconst loose = (v: unknown) => typeof v === 'function' || isObject(v)\n\n/**\n * Column arrays of the same shape: same length, same keys per column and equal primitive values;\n * functions and nested objects (`format`, `cell`, `filter`, …) may be new references.\n */\nfunction sameShape(a: unknown, b: unknown): boolean {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false\n for (let i = 0; i < a.length; i++) {\n const x: unknown = a[i]\n const y: unknown = b[i]\n if (Object.is(x, y)) continue\n if (!isObject(x) || !isObject(y)) return false\n const keys = Object.keys(x)\n if (keys.length !== Object.keys(y).length) return false\n for (const k of keys) {\n if (!Object.hasOwn(y, k)) return false\n const vx = x[k]\n const vy = y[k]\n if (Object.is(vx, vy)) continue\n if (!(loose(vx) && loose(vy) && typeof vx === typeof vy)) return false\n }\n }\n return true\n}\n\n// --- dev: DK_UNSTABLE_COLUMNS / DK_UNSTABLE_OPTION -----------------------------------------------\n\n/** The first function option of a feature that is a new reference: `features[i].<option>`. */\nfunction changedFeatureOption(a: unknown, b: unknown): string | undefined {\n if (!Array.isArray(a) || !Array.isArray(b) || a === b) return undefined\n for (let i = 0; i < a.length; i++) {\n const f = a[i] as AnyFeature | undefined\n const g = b[i] as AnyFeature | undefined\n if (!f || !g || f === g || f.name !== g.name) continue\n if (!isOptionsDefinition(f.options) || !isOptionsDefinition(g.options)) continue\n const fv = f.options.values\n const gv = g.options.values\n if (!fv || !gv) continue\n for (const k of Object.keys(fv)) {\n if (typeof fv[k] === 'function' && fv[k] !== gv[k]) return `features[${i}].${k}`\n }\n }\n return undefined\n}\n\n/** Counts renders in a row that pass a new reference for the same thing; reports each once. */\nfunction checkUnstable(inst: Instance, options: Options) {\n const seen = inst.seen\n inst.seen = options\n const changed = (k: string) => !Object.is(options[k], seen[k])\n const fn = (k: string) =>\n changed(k) && typeof options[k] === 'function' && typeof seen[k] === 'function'\n track(inst, 'columns', changed('columns') && sameShape(options.columns, seen.columns))\n track(inst, 'data', changed('data') && sameRows(options.data, seen.data))\n track(inst, 'fetcher', fn('fetcher'))\n track(inst, 'rowKey', fn('rowKey'))\n const option = changedFeatureOption(options.features, seen.features)\n track(inst, 'features', option !== undefined, option)\n}\n\nfunction track(inst: Instance, key: string, unstable: boolean, option = key) {\n const n = unstable ? (inst.unstable.get(key) ?? 0) + 1 : 0\n inst.unstable.set(key, n)\n if (n < UNSTABLE_AFTER || inst.warned.has(key)) return\n inst.warned.add(key)\n if (key === 'columns') emitTableDiagnostic(inst.table, 'DK_UNSTABLE_COLUMNS', { renders: n })\n else emitTableDiagnostic(inst.table, 'DK_UNSTABLE_OPTION', { option, renders: n })\n}\n","{\n \"name\": \"@datakable/react\",\n \"version\": \"1.0.1\",\n \"description\": \"React bindings for DataKable — useDataTable hook and DataTable component.\",\n \"license\": \"MIT\",\n \"author\": \"Supakit Kitjanabumrungsak\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Ink01101011/datakable.git\",\n \"directory\": \"packages/react\"\n },\n \"homepage\": \"https://github.com/Ink01101011/datakable#readme\",\n \"bugs\": \"https://github.com/Ink01101011/datakable/issues\",\n \"keywords\": [\n \"react\",\n \"datatable\",\n \"table\",\n \"data-grid\",\n \"typescript\",\n \"type-safe\",\n \"headless\"\n ],\n \"type\": \"module\",\n \"sideEffects\": [\n \"./dist/styles.css\"\n ],\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n },\n \"./styles.css\": \"./dist/styles.css\",\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc -p tsconfig.json\",\n \"check:pkg\": \"publint --strict && attw --pack . --profile node16 --exclude-entrypoints styles.css && node scripts/check-catalog.mjs\",\n \"check:catalog\": \"node scripts/check-catalog.mjs\"\n },\n \"dependencies\": {\n \"@datakable/core\": \"workspace:^\"\n },\n \"peerDependencies\": {\n \"react\": \">=18\"\n }\n}\n"],"mappings":"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","names":["value"]}
|