capitalsix-data-table 0.1.0 → 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ DataTable: () => DataTable
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/DataTable.ts
28
+ var DataTable = class {
29
+ constructor(initialRows = []) {
30
+ this.rows = [];
31
+ this.getRows = (predicate) => {
32
+ return predicate ? this.rows.filter(predicate) : this.rows;
33
+ };
34
+ this.setRows = (newRows) => {
35
+ this.rows.length = 0;
36
+ this.rows.push(...newRows);
37
+ };
38
+ this.insertRows = (newRows, primaryKey) => {
39
+ if (primaryKey) {
40
+ if (this.rows.some((row) => newRows.findIndex((r) => r[primaryKey] === row[primaryKey]) !== -1)) {
41
+ throw new Error(
42
+ `Duplicate primary key value found in existing rows for key: ${String(primaryKey)}`
43
+ );
44
+ }
45
+ }
46
+ this.rows.push(...newRows);
47
+ };
48
+ this.updateRows = (predicate, update, primaryKey) => {
49
+ const updatedRows = this.rows.filter(predicate);
50
+ let updateFunction;
51
+ if (typeof update === "function") {
52
+ updateFunction = update;
53
+ } else if (primaryKey === void 0) {
54
+ throw new Error("Primary key must be provided when update is an object.");
55
+ } else {
56
+ updateFunction = (updateRow) => {
57
+ Object.assign(updateRow, { ...update, [primaryKey]: updateRow[primaryKey] });
58
+ };
59
+ }
60
+ for (let i = 0; i < this.rows.length; i++) {
61
+ if (predicate(this.rows[i])) {
62
+ updateFunction(this.rows[i]);
63
+ }
64
+ }
65
+ return updatedRows;
66
+ };
67
+ this.upsertRows = (newRows, primaryKey) => {
68
+ const result = { inserted: [], updated: [] };
69
+ const existingRowsMap = new Map(this.rows.map((row) => [row[primaryKey], row]));
70
+ for (const newRow of newRows) {
71
+ const key = newRow[primaryKey];
72
+ if (existingRowsMap.has(key)) {
73
+ Object.assign(existingRowsMap.get(key), newRow);
74
+ result.updated.push(newRow);
75
+ } else {
76
+ this.rows.push(newRow);
77
+ result.inserted.push(newRow);
78
+ }
79
+ }
80
+ return result;
81
+ };
82
+ this.deleteRows = (predicate) => {
83
+ const deletedRows = this.rows.filter(predicate);
84
+ for (let i = this.rows.length - 1; i >= 0; i--) {
85
+ if (predicate(this.rows[i])) {
86
+ this.rows.splice(i, 1);
87
+ }
88
+ }
89
+ return deletedRows;
90
+ };
91
+ this.sortRows = (compareFn) => {
92
+ this.rows.sort(compareFn);
93
+ };
94
+ this.rows = initialRows;
95
+ }
96
+ };
97
+ // Annotate the CommonJS export names for ESM import in node:
98
+ 0 && (module.exports = {
99
+ DataTable
100
+ });
101
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/DataTable.ts"],"sourcesContent":["export { DataTable, type IDataTable } from './DataTable';\n","/**\r\n * Minimal initializer contract for replacing all rows in the table.\r\n */\r\nexport interface IDataTableInitial<T extends object> {\r\n /**\r\n * Replaces all current rows with the provided rows.\r\n */\r\n setRows: (rows: T[]) => void;\r\n}\r\n\r\n/**\r\n * Result of an upsert operation.\r\n * `inserted` contains rows that did not exist yet.\r\n * `updated` contains rows that matched an existing primary key.\r\n */\r\nexport interface DataTableUpsertResult<T extends object> {\r\n inserted: T[];\r\n updated: T[];\r\n}\r\n\r\n/**\r\n * Table-like CRUD and query operations for in-memory rows.\r\n */\r\nexport interface IDataTable<T extends object> {\r\n /**\r\n * Returns all rows, or only rows matching the predicate when provided.\r\n */\r\n getRows: (predicate?: (row: T) => boolean) => T[];\r\n\r\n /**\r\n * Appends rows to the table.\r\n * When `primaryKey` is provided, the method validates that no incoming key\r\n * already exists in the current table.\r\n */\r\n insertRows: (rows: T[], primaryKey?: keyof T) => void;\r\n\r\n /**\r\n * Updates all rows that match `predicate`.\r\n *\r\n * - When `update` is a function, the function mutates each matched row.\r\n * - When `update` is an object, `primaryKey` is required and preserved on each row.\r\n *\r\n * Returns the matched rows by reference (already reflecting any applied mutations).\r\n */\r\n updateRows: (\r\n predicate: (row: T) => boolean,\r\n update: T | ((updateRow: T) => void),\r\n primaryKey?: keyof T) => T[];\r\n\r\n /**\r\n * Upserts rows by `primaryKey`.\r\n *\r\n * - If a matching key exists, the existing row is updated in place.\r\n * - If no matching key exists, the row is inserted.\r\n *\r\n * Returns a `DataTableUpsertResult` where:\r\n * - `updated` contains the incoming rows that matched existing keys.\r\n * - `inserted` contains the incoming rows that were newly added.\r\n */\r\n upsertRows: (rows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;\r\n\r\n /**\r\n * Deletes matching rows and returns the deleted rows.\r\n */\r\n deleteRows: (predicate: (row: T) => boolean) => T[];\r\n \r\n /**\r\n * Sorts rows in place with the provided compare function.\r\n */\r\n sortRows: (compareFn: (a: T, b: T) => number) => void;\r\n}\r\n\r\n/**\r\n * Generic in-memory data table with mutable row operations.\r\n */\r\nexport class DataTable<T extends object> implements IDataTable<T>, IDataTableInitial<T> {\r\n private rows: T[] = [];\r\n\r\n public constructor(initialRows: T[] = []) {\r\n this.rows = initialRows;\r\n }\r\n\r\n public getRows = (predicate?: (row: T) => boolean): T[] => {\r\n return predicate ? this.rows.filter(predicate) : this.rows;\r\n };\r\n\r\n public setRows = (newRows: T[]): void => {\r\n this.rows.length = 0;\r\n this.rows.push(...newRows);\r\n };\r\n\r\n public insertRows = (newRows: T[], primaryKey?: keyof T): void => {\r\n if (primaryKey) {\r\n // Reject insert when any incoming row key already exists in the current table.\r\n if (this.rows.some(row => newRows.findIndex(r => r[primaryKey] === row[primaryKey]) !== -1))\r\n {\r\n throw new Error(\r\n `Duplicate primary key value found in existing rows for key: ${String(primaryKey)}`);\r\n }\r\n }\r\n this.rows.push(...newRows);\r\n };\r\n\r\n public updateRows = (\r\n predicate: (row: T) => boolean,\r\n update: T | ((updateRow: T) => void),\r\n primaryKey?: keyof T): T[] => {\r\n // Keep references to matched rows; these objects are mutated in place below.\r\n const updatedRows: T[] = this.rows.filter(predicate);\r\n\r\n let updateFunction: (updateRow: T) => void;\r\n if (typeof update === 'function') {\r\n updateFunction = update as (updateRow: T) => void;\r\n } else if (primaryKey === undefined) {\r\n throw new Error('Primary key must be provided when update is an object.');\r\n } else {\r\n // Preserve the original primary key when doing object-style updates.\r\n updateFunction = (updateRow: T): void => {\r\n Object.assign(updateRow, { ...update, [primaryKey!]: updateRow[primaryKey!] });\r\n };\r\n }\r\n\r\n for (let i = 0; i < this.rows.length; i++) {\r\n if (predicate(this.rows[i])) {\r\n updateFunction(this.rows[i]);\r\n }\r\n }\r\n\r\n return updatedRows;\r\n };\r\n\r\n public upsertRows = (newRows: T[], primaryKey: keyof T): DataTableUpsertResult<T> => {\r\n const result: DataTableUpsertResult<T> = { inserted: [], updated: [] };\r\n // Index existing rows by primary key for efficient upsert lookup.\r\n const existingRowsMap = new Map(this.rows.map(row => [ row[primaryKey], row ]));\r\n for (const newRow of newRows) {\r\n const key = newRow[primaryKey];\r\n if (existingRowsMap.has(key)) {\r\n Object.assign(existingRowsMap.get(key)!, newRow);\r\n result.updated.push(newRow);\r\n } else {\r\n this.rows.push(newRow);\r\n result.inserted.push(newRow);\r\n }\r\n }\r\n return result;\r\n };\r\n\r\n public deleteRows = (predicate: (row: T) => boolean): T[] => {\r\n const deletedRows = this.rows.filter(predicate);\r\n\r\n // Iterate backwards to safely remove items from the same array.\r\n for (let i = this.rows.length - 1; i >= 0; i--) {\r\n if (predicate(this.rows[i])) {\r\n this.rows.splice(i, 1);\r\n }\r\n }\r\n\r\n return deletedRows;\r\n };\r\n\r\n public sortRows = (compareFn: (a: T, b: T) => number): void => {\r\n this.rows.sort(compareFn);\r\n };\r\n}\r\n\r\nexport default DataTable;\r\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC2EO,IAAM,YAAN,MAAiF;AAAA,EAG/E,YAAY,cAAmB,CAAC,GAAG;AAF1C,SAAQ,OAAY,CAAC;AAMrB,SAAO,UAAU,CAAC,cAAyC;AACzD,aAAO,YAAY,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK;AAAA,IACxD;AAEA,SAAO,UAAU,CAAC,YAAuB;AACvC,WAAK,KAAK,SAAS;AACnB,WAAK,KAAK,KAAK,GAAG,OAAO;AAAA,IAC3B;AAEA,SAAO,aAAa,CAAC,SAAc,eAA+B;AAChE,UAAI,YAAY;AAEd,YAAI,KAAK,KAAK,KAAK,SAAO,QAAQ,UAAU,OAAK,EAAE,UAAU,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,GAC1F;AACE,gBAAM,IAAI;AAAA,YACR,+DAA+D,OAAO,UAAU,CAAC;AAAA,UAAE;AAAA,QACvF;AAAA,MACF;AACA,WAAK,KAAK,KAAK,GAAG,OAAO;AAAA,IAC3B;AAEA,SAAO,aAAa,CAClB,WACA,QACA,eAA8B;AAE9B,YAAM,cAAmB,KAAK,KAAK,OAAO,SAAS;AAEnD,UAAI;AACJ,UAAI,OAAO,WAAW,YAAY;AAChC,yBAAiB;AAAA,MACnB,WAAW,eAAe,QAAW;AACnC,cAAM,IAAI,MAAM,wDAAwD;AAAA,MAC1E,OAAO;AAEL,yBAAiB,CAAC,cAAuB;AACvC,iBAAO,OAAO,WAAW,EAAE,GAAG,QAAQ,CAAC,UAAW,GAAG,UAAU,UAAW,EAAE,CAAC;AAAA,QAC/E;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;AACzC,YAAI,UAAU,KAAK,KAAK,CAAC,CAAC,GAAG;AAC3B,yBAAe,KAAK,KAAK,CAAC,CAAC;AAAA,QAC7B;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,SAAO,aAAa,CAAC,SAAc,eAAkD;AACnF,YAAM,SAAmC,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,EAAE;AAErE,YAAM,kBAAkB,IAAI,IAAI,KAAK,KAAK,IAAI,SAAO,CAAE,IAAI,UAAU,GAAG,GAAI,CAAC,CAAC;AAC9E,iBAAW,UAAU,SAAS;AAC5B,cAAM,MAAM,OAAO,UAAU;AAC7B,YAAI,gBAAgB,IAAI,GAAG,GAAG;AAC5B,iBAAO,OAAO,gBAAgB,IAAI,GAAG,GAAI,MAAM;AAC/C,iBAAO,QAAQ,KAAK,MAAM;AAAA,QAC5B,OAAO;AACL,eAAK,KAAK,KAAK,MAAM;AACrB,iBAAO,SAAS,KAAK,MAAM;AAAA,QAC7B;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,SAAO,aAAa,CAAC,cAAwC;AAC3D,YAAM,cAAc,KAAK,KAAK,OAAO,SAAS;AAG9C,eAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAI,UAAU,KAAK,KAAK,CAAC,CAAC,GAAG;AAC3B,eAAK,KAAK,OAAO,GAAG,CAAC;AAAA,QACvB;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,SAAO,WAAW,CAAC,cAA4C;AAC7D,WAAK,KAAK,KAAK,SAAS;AAAA,IAC1B;AApFE,SAAK,OAAO;AAAA,EACd;AAoFF;","names":[]}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Minimal initializer contract for replacing all rows in the table.
3
+ */
4
+ interface IDataTableInitial<T extends object> {
5
+ /**
6
+ * Replaces all current rows with the provided rows.
7
+ */
8
+ setRows: (rows: T[]) => void;
9
+ }
10
+ /**
11
+ * Result of an upsert operation.
12
+ * `inserted` contains rows that did not exist yet.
13
+ * `updated` contains rows that matched an existing primary key.
14
+ */
15
+ interface DataTableUpsertResult<T extends object> {
16
+ inserted: T[];
17
+ updated: T[];
18
+ }
19
+ /**
20
+ * Table-like CRUD and query operations for in-memory rows.
21
+ */
22
+ interface IDataTable<T extends object> {
23
+ /**
24
+ * Returns all rows, or only rows matching the predicate when provided.
25
+ */
26
+ getRows: (predicate?: (row: T) => boolean) => T[];
27
+ /**
28
+ * Appends rows to the table.
29
+ * When `primaryKey` is provided, the method validates that no incoming key
30
+ * already exists in the current table.
31
+ */
32
+ insertRows: (rows: T[], primaryKey?: keyof T) => void;
33
+ /**
34
+ * Updates all rows that match `predicate`.
35
+ *
36
+ * - When `update` is a function, the function mutates each matched row.
37
+ * - When `update` is an object, `primaryKey` is required and preserved on each row.
38
+ *
39
+ * Returns the matched rows by reference (already reflecting any applied mutations).
40
+ */
41
+ updateRows: (predicate: (row: T) => boolean, update: T | ((updateRow: T) => void), primaryKey?: keyof T) => T[];
42
+ /**
43
+ * Upserts rows by `primaryKey`.
44
+ *
45
+ * - If a matching key exists, the existing row is updated in place.
46
+ * - If no matching key exists, the row is inserted.
47
+ *
48
+ * Returns a `DataTableUpsertResult` where:
49
+ * - `updated` contains the incoming rows that matched existing keys.
50
+ * - `inserted` contains the incoming rows that were newly added.
51
+ */
52
+ upsertRows: (rows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;
53
+ /**
54
+ * Deletes matching rows and returns the deleted rows.
55
+ */
56
+ deleteRows: (predicate: (row: T) => boolean) => T[];
57
+ /**
58
+ * Sorts rows in place with the provided compare function.
59
+ */
60
+ sortRows: (compareFn: (a: T, b: T) => number) => void;
61
+ }
62
+ /**
63
+ * Generic in-memory data table with mutable row operations.
64
+ */
65
+ declare class DataTable<T extends object> implements IDataTable<T>, IDataTableInitial<T> {
66
+ private rows;
67
+ constructor(initialRows?: T[]);
68
+ getRows: (predicate?: (row: T) => boolean) => T[];
69
+ setRows: (newRows: T[]) => void;
70
+ insertRows: (newRows: T[], primaryKey?: keyof T) => void;
71
+ updateRows: (predicate: (row: T) => boolean, update: T | ((updateRow: T) => void), primaryKey?: keyof T) => T[];
72
+ upsertRows: (newRows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;
73
+ deleteRows: (predicate: (row: T) => boolean) => T[];
74
+ sortRows: (compareFn: (a: T, b: T) => number) => void;
75
+ }
76
+
77
+ export { DataTable, type IDataTable };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Minimal initializer contract for replacing all rows in the table.
3
+ */
4
+ interface IDataTableInitial<T extends object> {
5
+ /**
6
+ * Replaces all current rows with the provided rows.
7
+ */
8
+ setRows: (rows: T[]) => void;
9
+ }
10
+ /**
11
+ * Result of an upsert operation.
12
+ * `inserted` contains rows that did not exist yet.
13
+ * `updated` contains rows that matched an existing primary key.
14
+ */
15
+ interface DataTableUpsertResult<T extends object> {
16
+ inserted: T[];
17
+ updated: T[];
18
+ }
19
+ /**
20
+ * Table-like CRUD and query operations for in-memory rows.
21
+ */
22
+ interface IDataTable<T extends object> {
23
+ /**
24
+ * Returns all rows, or only rows matching the predicate when provided.
25
+ */
26
+ getRows: (predicate?: (row: T) => boolean) => T[];
27
+ /**
28
+ * Appends rows to the table.
29
+ * When `primaryKey` is provided, the method validates that no incoming key
30
+ * already exists in the current table.
31
+ */
32
+ insertRows: (rows: T[], primaryKey?: keyof T) => void;
33
+ /**
34
+ * Updates all rows that match `predicate`.
35
+ *
36
+ * - When `update` is a function, the function mutates each matched row.
37
+ * - When `update` is an object, `primaryKey` is required and preserved on each row.
38
+ *
39
+ * Returns the matched rows by reference (already reflecting any applied mutations).
40
+ */
41
+ updateRows: (predicate: (row: T) => boolean, update: T | ((updateRow: T) => void), primaryKey?: keyof T) => T[];
42
+ /**
43
+ * Upserts rows by `primaryKey`.
44
+ *
45
+ * - If a matching key exists, the existing row is updated in place.
46
+ * - If no matching key exists, the row is inserted.
47
+ *
48
+ * Returns a `DataTableUpsertResult` where:
49
+ * - `updated` contains the incoming rows that matched existing keys.
50
+ * - `inserted` contains the incoming rows that were newly added.
51
+ */
52
+ upsertRows: (rows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;
53
+ /**
54
+ * Deletes matching rows and returns the deleted rows.
55
+ */
56
+ deleteRows: (predicate: (row: T) => boolean) => T[];
57
+ /**
58
+ * Sorts rows in place with the provided compare function.
59
+ */
60
+ sortRows: (compareFn: (a: T, b: T) => number) => void;
61
+ }
62
+ /**
63
+ * Generic in-memory data table with mutable row operations.
64
+ */
65
+ declare class DataTable<T extends object> implements IDataTable<T>, IDataTableInitial<T> {
66
+ private rows;
67
+ constructor(initialRows?: T[]);
68
+ getRows: (predicate?: (row: T) => boolean) => T[];
69
+ setRows: (newRows: T[]) => void;
70
+ insertRows: (newRows: T[], primaryKey?: keyof T) => void;
71
+ updateRows: (predicate: (row: T) => boolean, update: T | ((updateRow: T) => void), primaryKey?: keyof T) => T[];
72
+ upsertRows: (newRows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;
73
+ deleteRows: (predicate: (row: T) => boolean) => T[];
74
+ sortRows: (compareFn: (a: T, b: T) => number) => void;
75
+ }
76
+
77
+ export { DataTable, type IDataTable };
package/dist/index.js ADDED
@@ -0,0 +1,74 @@
1
+ // src/DataTable.ts
2
+ var DataTable = class {
3
+ constructor(initialRows = []) {
4
+ this.rows = [];
5
+ this.getRows = (predicate) => {
6
+ return predicate ? this.rows.filter(predicate) : this.rows;
7
+ };
8
+ this.setRows = (newRows) => {
9
+ this.rows.length = 0;
10
+ this.rows.push(...newRows);
11
+ };
12
+ this.insertRows = (newRows, primaryKey) => {
13
+ if (primaryKey) {
14
+ if (this.rows.some((row) => newRows.findIndex((r) => r[primaryKey] === row[primaryKey]) !== -1)) {
15
+ throw new Error(
16
+ `Duplicate primary key value found in existing rows for key: ${String(primaryKey)}`
17
+ );
18
+ }
19
+ }
20
+ this.rows.push(...newRows);
21
+ };
22
+ this.updateRows = (predicate, update, primaryKey) => {
23
+ const updatedRows = this.rows.filter(predicate);
24
+ let updateFunction;
25
+ if (typeof update === "function") {
26
+ updateFunction = update;
27
+ } else if (primaryKey === void 0) {
28
+ throw new Error("Primary key must be provided when update is an object.");
29
+ } else {
30
+ updateFunction = (updateRow) => {
31
+ Object.assign(updateRow, { ...update, [primaryKey]: updateRow[primaryKey] });
32
+ };
33
+ }
34
+ for (let i = 0; i < this.rows.length; i++) {
35
+ if (predicate(this.rows[i])) {
36
+ updateFunction(this.rows[i]);
37
+ }
38
+ }
39
+ return updatedRows;
40
+ };
41
+ this.upsertRows = (newRows, primaryKey) => {
42
+ const result = { inserted: [], updated: [] };
43
+ const existingRowsMap = new Map(this.rows.map((row) => [row[primaryKey], row]));
44
+ for (const newRow of newRows) {
45
+ const key = newRow[primaryKey];
46
+ if (existingRowsMap.has(key)) {
47
+ Object.assign(existingRowsMap.get(key), newRow);
48
+ result.updated.push(newRow);
49
+ } else {
50
+ this.rows.push(newRow);
51
+ result.inserted.push(newRow);
52
+ }
53
+ }
54
+ return result;
55
+ };
56
+ this.deleteRows = (predicate) => {
57
+ const deletedRows = this.rows.filter(predicate);
58
+ for (let i = this.rows.length - 1; i >= 0; i--) {
59
+ if (predicate(this.rows[i])) {
60
+ this.rows.splice(i, 1);
61
+ }
62
+ }
63
+ return deletedRows;
64
+ };
65
+ this.sortRows = (compareFn) => {
66
+ this.rows.sort(compareFn);
67
+ };
68
+ this.rows = initialRows;
69
+ }
70
+ };
71
+ export {
72
+ DataTable
73
+ };
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/DataTable.ts"],"sourcesContent":["/**\r\n * Minimal initializer contract for replacing all rows in the table.\r\n */\r\nexport interface IDataTableInitial<T extends object> {\r\n /**\r\n * Replaces all current rows with the provided rows.\r\n */\r\n setRows: (rows: T[]) => void;\r\n}\r\n\r\n/**\r\n * Result of an upsert operation.\r\n * `inserted` contains rows that did not exist yet.\r\n * `updated` contains rows that matched an existing primary key.\r\n */\r\nexport interface DataTableUpsertResult<T extends object> {\r\n inserted: T[];\r\n updated: T[];\r\n}\r\n\r\n/**\r\n * Table-like CRUD and query operations for in-memory rows.\r\n */\r\nexport interface IDataTable<T extends object> {\r\n /**\r\n * Returns all rows, or only rows matching the predicate when provided.\r\n */\r\n getRows: (predicate?: (row: T) => boolean) => T[];\r\n\r\n /**\r\n * Appends rows to the table.\r\n * When `primaryKey` is provided, the method validates that no incoming key\r\n * already exists in the current table.\r\n */\r\n insertRows: (rows: T[], primaryKey?: keyof T) => void;\r\n\r\n /**\r\n * Updates all rows that match `predicate`.\r\n *\r\n * - When `update` is a function, the function mutates each matched row.\r\n * - When `update` is an object, `primaryKey` is required and preserved on each row.\r\n *\r\n * Returns the matched rows by reference (already reflecting any applied mutations).\r\n */\r\n updateRows: (\r\n predicate: (row: T) => boolean,\r\n update: T | ((updateRow: T) => void),\r\n primaryKey?: keyof T) => T[];\r\n\r\n /**\r\n * Upserts rows by `primaryKey`.\r\n *\r\n * - If a matching key exists, the existing row is updated in place.\r\n * - If no matching key exists, the row is inserted.\r\n *\r\n * Returns a `DataTableUpsertResult` where:\r\n * - `updated` contains the incoming rows that matched existing keys.\r\n * - `inserted` contains the incoming rows that were newly added.\r\n */\r\n upsertRows: (rows: T[], primaryKey: keyof T) => DataTableUpsertResult<T>;\r\n\r\n /**\r\n * Deletes matching rows and returns the deleted rows.\r\n */\r\n deleteRows: (predicate: (row: T) => boolean) => T[];\r\n \r\n /**\r\n * Sorts rows in place with the provided compare function.\r\n */\r\n sortRows: (compareFn: (a: T, b: T) => number) => void;\r\n}\r\n\r\n/**\r\n * Generic in-memory data table with mutable row operations.\r\n */\r\nexport class DataTable<T extends object> implements IDataTable<T>, IDataTableInitial<T> {\r\n private rows: T[] = [];\r\n\r\n public constructor(initialRows: T[] = []) {\r\n this.rows = initialRows;\r\n }\r\n\r\n public getRows = (predicate?: (row: T) => boolean): T[] => {\r\n return predicate ? this.rows.filter(predicate) : this.rows;\r\n };\r\n\r\n public setRows = (newRows: T[]): void => {\r\n this.rows.length = 0;\r\n this.rows.push(...newRows);\r\n };\r\n\r\n public insertRows = (newRows: T[], primaryKey?: keyof T): void => {\r\n if (primaryKey) {\r\n // Reject insert when any incoming row key already exists in the current table.\r\n if (this.rows.some(row => newRows.findIndex(r => r[primaryKey] === row[primaryKey]) !== -1))\r\n {\r\n throw new Error(\r\n `Duplicate primary key value found in existing rows for key: ${String(primaryKey)}`);\r\n }\r\n }\r\n this.rows.push(...newRows);\r\n };\r\n\r\n public updateRows = (\r\n predicate: (row: T) => boolean,\r\n update: T | ((updateRow: T) => void),\r\n primaryKey?: keyof T): T[] => {\r\n // Keep references to matched rows; these objects are mutated in place below.\r\n const updatedRows: T[] = this.rows.filter(predicate);\r\n\r\n let updateFunction: (updateRow: T) => void;\r\n if (typeof update === 'function') {\r\n updateFunction = update as (updateRow: T) => void;\r\n } else if (primaryKey === undefined) {\r\n throw new Error('Primary key must be provided when update is an object.');\r\n } else {\r\n // Preserve the original primary key when doing object-style updates.\r\n updateFunction = (updateRow: T): void => {\r\n Object.assign(updateRow, { ...update, [primaryKey!]: updateRow[primaryKey!] });\r\n };\r\n }\r\n\r\n for (let i = 0; i < this.rows.length; i++) {\r\n if (predicate(this.rows[i])) {\r\n updateFunction(this.rows[i]);\r\n }\r\n }\r\n\r\n return updatedRows;\r\n };\r\n\r\n public upsertRows = (newRows: T[], primaryKey: keyof T): DataTableUpsertResult<T> => {\r\n const result: DataTableUpsertResult<T> = { inserted: [], updated: [] };\r\n // Index existing rows by primary key for efficient upsert lookup.\r\n const existingRowsMap = new Map(this.rows.map(row => [ row[primaryKey], row ]));\r\n for (const newRow of newRows) {\r\n const key = newRow[primaryKey];\r\n if (existingRowsMap.has(key)) {\r\n Object.assign(existingRowsMap.get(key)!, newRow);\r\n result.updated.push(newRow);\r\n } else {\r\n this.rows.push(newRow);\r\n result.inserted.push(newRow);\r\n }\r\n }\r\n return result;\r\n };\r\n\r\n public deleteRows = (predicate: (row: T) => boolean): T[] => {\r\n const deletedRows = this.rows.filter(predicate);\r\n\r\n // Iterate backwards to safely remove items from the same array.\r\n for (let i = this.rows.length - 1; i >= 0; i--) {\r\n if (predicate(this.rows[i])) {\r\n this.rows.splice(i, 1);\r\n }\r\n }\r\n\r\n return deletedRows;\r\n };\r\n\r\n public sortRows = (compareFn: (a: T, b: T) => number): void => {\r\n this.rows.sort(compareFn);\r\n };\r\n}\r\n\r\nexport default DataTable;\r\n"],"mappings":";AA2EO,IAAM,YAAN,MAAiF;AAAA,EAG/E,YAAY,cAAmB,CAAC,GAAG;AAF1C,SAAQ,OAAY,CAAC;AAMrB,SAAO,UAAU,CAAC,cAAyC;AACzD,aAAO,YAAY,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK;AAAA,IACxD;AAEA,SAAO,UAAU,CAAC,YAAuB;AACvC,WAAK,KAAK,SAAS;AACnB,WAAK,KAAK,KAAK,GAAG,OAAO;AAAA,IAC3B;AAEA,SAAO,aAAa,CAAC,SAAc,eAA+B;AAChE,UAAI,YAAY;AAEd,YAAI,KAAK,KAAK,KAAK,SAAO,QAAQ,UAAU,OAAK,EAAE,UAAU,MAAM,IAAI,UAAU,CAAC,MAAM,EAAE,GAC1F;AACE,gBAAM,IAAI;AAAA,YACR,+DAA+D,OAAO,UAAU,CAAC;AAAA,UAAE;AAAA,QACvF;AAAA,MACF;AACA,WAAK,KAAK,KAAK,GAAG,OAAO;AAAA,IAC3B;AAEA,SAAO,aAAa,CAClB,WACA,QACA,eAA8B;AAE9B,YAAM,cAAmB,KAAK,KAAK,OAAO,SAAS;AAEnD,UAAI;AACJ,UAAI,OAAO,WAAW,YAAY;AAChC,yBAAiB;AAAA,MACnB,WAAW,eAAe,QAAW;AACnC,cAAM,IAAI,MAAM,wDAAwD;AAAA,MAC1E,OAAO;AAEL,yBAAiB,CAAC,cAAuB;AACvC,iBAAO,OAAO,WAAW,EAAE,GAAG,QAAQ,CAAC,UAAW,GAAG,UAAU,UAAW,EAAE,CAAC;AAAA,QAC/E;AAAA,MACF;AAEA,eAAS,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,KAAK;AACzC,YAAI,UAAU,KAAK,KAAK,CAAC,CAAC,GAAG;AAC3B,yBAAe,KAAK,KAAK,CAAC,CAAC;AAAA,QAC7B;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,SAAO,aAAa,CAAC,SAAc,eAAkD;AACnF,YAAM,SAAmC,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,EAAE;AAErE,YAAM,kBAAkB,IAAI,IAAI,KAAK,KAAK,IAAI,SAAO,CAAE,IAAI,UAAU,GAAG,GAAI,CAAC,CAAC;AAC9E,iBAAW,UAAU,SAAS;AAC5B,cAAM,MAAM,OAAO,UAAU;AAC7B,YAAI,gBAAgB,IAAI,GAAG,GAAG;AAC5B,iBAAO,OAAO,gBAAgB,IAAI,GAAG,GAAI,MAAM;AAC/C,iBAAO,QAAQ,KAAK,MAAM;AAAA,QAC5B,OAAO;AACL,eAAK,KAAK,KAAK,MAAM;AACrB,iBAAO,SAAS,KAAK,MAAM;AAAA,QAC7B;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,SAAO,aAAa,CAAC,cAAwC;AAC3D,YAAM,cAAc,KAAK,KAAK,OAAO,SAAS;AAG9C,eAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AAC9C,YAAI,UAAU,KAAK,KAAK,CAAC,CAAC,GAAG;AAC3B,eAAK,KAAK,OAAO,GAAG,CAAC;AAAA,QACvB;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAEA,SAAO,WAAW,CAAC,cAA4C;AAC7D,WAAK,KAAK,KAAK,SAAS;AAAA,IAC1B;AApFE,SAAK,OAAO;AAAA,EACd;AAoFF;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "capitalsix-data-table",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "A lightweight, framework-agnostic in-memory data table with typed CRUD operations: insert, update, upsert, delete, sort, and query rows.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -26,6 +26,12 @@
26
26
  "repository": {
27
27
  "url": "https://github.com/capital-six/data-table"
28
28
  },
29
+ "keywords": [
30
+ "react",
31
+ "global",
32
+ "state",
33
+ "typescript"
34
+ ],
29
35
  "ignore": [
30
36
  "src/",
31
37
  "node_modules/",