@wszerad/items 0.0.6 → 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.
@@ -0,0 +1,50 @@
1
+ import { Items } from './src'
2
+
3
+ interface User {
4
+ id: number
5
+ name: string
6
+ }
7
+
8
+ interface Book {
9
+ isbn: string
10
+ title: string
11
+ }
12
+
13
+ interface Product {
14
+ sku: string
15
+ name: string
16
+ code: number
17
+ }
18
+
19
+ console.log('=== Type Inference Tests ===\n')
20
+
21
+ // Test 1: No selectId provided - I is inferred from User['id'] = number
22
+ console.log('Test 1: No selectId, infer from E["id"]')
23
+ const users = new Items<User>([{ id: 1, name: 'Alice' }])
24
+ const userId: number = users.getIds()[0]! // ✓ Type is correctly number
25
+ console.log(' User IDs type:', typeof userId, '✓')
26
+
27
+ // Test 2: With custom selectId - I is inferred from selectId return type (string)
28
+ console.log('\nTest 2: With selectId, infer from selectId return type')
29
+ const books = new Items<Book, string>([], { selectId: (book) => book.isbn })
30
+ const addedBooks = books.insert({ isbn: '978-0', title: 'TypeScript Guide' })
31
+ const bookId: string = addedBooks.getIds()[0]! // ✓ Type is correctly string
32
+ console.log(' Book IDs type:', typeof bookId, '✓')
33
+
34
+ // Test 3: selectId returning different type than default id property
35
+ console.log('\nTest 3: selectId with different return type')
36
+ const products = new Items<Product, number>([], { selectId: (p) => p.code })
37
+ const addedProducts = products.insert({ sku: 'ABC', name: 'Widget', code: 12345 })
38
+ const productId: number = addedProducts.getIds()[0]! // ✓ Type is correctly number
39
+ console.log(' Product IDs type:', typeof productId, '✓')
40
+
41
+ // Test 4: Full type inference from initial items
42
+ console.log('\nTest 4: Complete inference from initial items')
43
+ const autoInferred = new Items([{ id: 999, name: 'Test' }])
44
+ const autoId: number = autoInferred.getIds()[0]! // ✓ Both E and I are inferred
45
+ console.log(' Auto-inferred ID type:', typeof autoId, '✓')
46
+
47
+ console.log('\n✓ All type inference tests passed!')
48
+
49
+
50
+
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2022"],
5
+ "module": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "resolveJsonModule": true,
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "skipLibCheck": true,
12
+ "noEmit": true,
13
+ "types": ["node", "vitest/globals"]
14
+ },
15
+ "include": ["src", "test", "vitest.config.ts"]
16
+ }
@@ -0,0 +1,13 @@
1
+ import { defineConfig } from 'tsdown';
2
+
3
+ export default defineConfig({
4
+ entry: {
5
+ index: 'src/index.ts'
6
+ },
7
+ outDir: 'dist',
8
+ format: ['esm'],
9
+ dts: true,
10
+ sourcemap: true,
11
+ clean: true
12
+ });
13
+
@@ -0,0 +1,9 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: 'node',
6
+ include: ['test/**/*.test.ts']
7
+ }
8
+ });
9
+
package/dist/index.d.mts DELETED
@@ -1,76 +0,0 @@
1
- import { diff } from "ohash/utils";
2
-
3
- //#region src/diff.d.ts
4
- interface ItemDiff<I, E> {
5
- id: I;
6
- changes: ReturnType<typeof diff>;
7
- }
8
- interface ItemsDiff<I, E> {
9
- added: I[];
10
- removed: I[];
11
- updated: ItemDiff<I, E>[];
12
- }
13
- //#endregion
14
- //#region src/selectId.d.ts
15
- type SelectId<I, E> = (entity: E) => I;
16
- //#endregion
17
- //#region src/selector.d.ts
18
- type SelectorFn<I, E> = (entity: E) => boolean;
19
- type Selector<I, E> = Iterable<I> | SelectorFn<I, E>;
20
- type Operation<I, E> = (entity: E | undefined, id: I) => void;
21
- //#endregion
22
- //#region src/updater.d.ts
23
- type UpdateFn<E> = (entity: E) => E;
24
- type Updater<I, E> = UpdateFn<E> | Partial<E>;
25
- //#endregion
26
- //#region src/Items.d.ts
27
- interface ItemsOptions<I, E> {
28
- selectId?: SelectId<I, E>;
29
- sortComparer?: false | ((a: E, b: E) => number);
30
- }
31
- interface ItemsState<I, E> {
32
- ids: I[];
33
- entities: Map<I, E>;
34
- }
35
- declare class Items<I, E> {
36
- private options;
37
- private state;
38
- constructor(items?: Iterable<E>, options?: ItemsOptions<I, E>);
39
- getIds(): I[];
40
- getEntities(): Map<I, E>;
41
- get length(): number;
42
- select(id: I): E | undefined;
43
- insert(entity: E): Items<I, E>;
44
- insertMany(entities: Iterable<E>): Items<I, E>;
45
- upsert(entity: E): Items<I, E>;
46
- upsertMany(entities: Iterable<E>): Items<I, E>;
47
- set(entity: E): Items<I, E>;
48
- setMany(entities: Iterable<E>): Items<I, E>;
49
- every(check: SelectorFn<I, E>): boolean;
50
- some(check: SelectorFn<I, E>): boolean;
51
- has(id: I): boolean;
52
- hasMany(select: Selector<I, E>): boolean;
53
- update(id: I, updater: Updater<I, E>): Items<I, E>;
54
- updateMany(select: Selector<I, E>, updater: Updater<I, E>): Items<I, E>;
55
- remove(id: I): Items<I, E>;
56
- removeMany(select: Selector<I, E>): Items<I, E>;
57
- clear(): Items<I, E>;
58
- filter(select: Selector<I, E>): Items<I, E>;
59
- page(page: number, pageSize: number): {
60
- items: NonNullable<E>[];
61
- page: number;
62
- pageSize: number;
63
- hasNext: boolean;
64
- hasPrevious: boolean;
65
- total: number;
66
- totalPages: number;
67
- };
68
- diff(base: Items<I, E>): ItemsDiff<I, E>;
69
- private sortIds;
70
- private selectId;
71
- private get sortComparer();
72
- [Symbol.iterator](): Iterator<E>;
73
- }
74
- //#endregion
75
- export { type ItemDiff, Items, type ItemsDiff, type ItemsOptions, type ItemsState, type Operation, type SelectId, type Selector, type SelectorFn, type UpdateFn, type Updater };
76
- //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs DELETED
@@ -1,194 +0,0 @@
1
- import { diff } from "ohash/utils";
2
-
3
- //#region src/selectId.ts
4
- function defaultSelectId(entity) {
5
- return entity.id;
6
- }
7
-
8
- //#endregion
9
- //#region src/selector.ts
10
- function selector(items, selector$1, operation) {
11
- if (typeof selector$1 === "function") items.getEntities().forEach((entity, id) => {
12
- if (selector$1(entity)) operation(entity, id);
13
- });
14
- else Array.from(selector$1).forEach((id) => operation(items.select(id), id));
15
- }
16
-
17
- //#endregion
18
- //#region src/diff.ts
19
- function itemsDiff(fromItems, toItems) {
20
- const ids = new Set(toItems.getIds());
21
- const baseIds = new Set(fromItems.getIds());
22
- const added = [];
23
- const updated = [];
24
- ids.forEach((id) => {
25
- if (!baseIds.has(id)) added.push(id);
26
- else {
27
- const changes = diff(fromItems.select(id), toItems.select(id));
28
- if (changes.length > 0) updated.push({
29
- id,
30
- changes
31
- });
32
- baseIds.delete(id);
33
- }
34
- });
35
- return {
36
- added,
37
- removed: [...baseIds],
38
- updated
39
- };
40
- }
41
-
42
- //#endregion
43
- //#region src/updater.ts
44
- function update(entity, updater) {
45
- return {
46
- ...entity,
47
- ...typeof updater === "function" ? updater(entity) : updater
48
- };
49
- }
50
-
51
- //#endregion
52
- //#region src/Items.ts
53
- var Items = class Items {
54
- state;
55
- constructor(items = [], options = {}) {
56
- this.options = options;
57
- const entities = new Map(Array.from(items).map((item) => {
58
- return [this.selectId(item), item];
59
- }));
60
- this.state = {
61
- ids: this.sortIds([...entities.keys()], entities),
62
- entities
63
- };
64
- }
65
- getIds() {
66
- return [...this.state.ids];
67
- }
68
- getEntities() {
69
- return new Map(this.state.entities);
70
- }
71
- get length() {
72
- return this.state.ids.length;
73
- }
74
- select(id) {
75
- return this.state.entities.get(id);
76
- }
77
- insert(entity) {
78
- return this.insertMany([entity]);
79
- }
80
- insertMany(entities) {
81
- return new Items([...this, ...Array.from(entities).filter((entity) => !this.has(this.selectId(entity)))], this.options);
82
- }
83
- upsert(entity) {
84
- return this.upsertMany([entity]);
85
- }
86
- upsertMany(entities) {
87
- const clone = this.getEntities();
88
- Array.from(entities).forEach((entity) => {
89
- const id = this.selectId(entity);
90
- const existing = clone.get(id);
91
- if (existing) clone.set(id, {
92
- ...existing,
93
- ...entity
94
- });
95
- else clone.set(id, entity);
96
- });
97
- return new Items(clone.values(), this.options);
98
- }
99
- set(entity) {
100
- return this.setMany([entity]);
101
- }
102
- setMany(entities) {
103
- return new Items([...this, ...entities], this.options);
104
- }
105
- every(check) {
106
- return this.getIds().every((id) => check(this.select(id)));
107
- }
108
- some(check) {
109
- return this.getIds().some((id) => check(this.select(id)));
110
- }
111
- has(id) {
112
- return this.state.ids.includes(id);
113
- }
114
- hasMany(select) {
115
- let failToFind = false;
116
- let result = false;
117
- selector(this, select, (entity) => {
118
- if (entity) result = true;
119
- else failToFind = true;
120
- });
121
- return !failToFind && result;
122
- }
123
- update(id, updater) {
124
- const entity = this.select(id);
125
- if (!entity) return this;
126
- const clone = this.getEntities();
127
- clone.set(id, update(entity, updater));
128
- return new Items(clone.values(), this.options);
129
- }
130
- updateMany(select, updater) {
131
- const clone = this.getEntities();
132
- selector(this, select, (entity, id) => {
133
- if (entity) clone.set(id, update(entity, updater));
134
- });
135
- return new Items(clone.values(), this.options);
136
- }
137
- remove(id) {
138
- const clone = this.getEntities();
139
- clone.delete(id);
140
- return new Items(clone.values(), this.options);
141
- }
142
- removeMany(select) {
143
- const clone = this.getEntities();
144
- selector(this, select, (_, id) => {
145
- clone.delete(id);
146
- });
147
- return new Items(clone.values(), this.options);
148
- }
149
- clear() {
150
- return new Items([], this.options);
151
- }
152
- filter(select) {
153
- const clone = /* @__PURE__ */ new Map();
154
- selector(this, select, (entity, id) => {
155
- if (entity) clone.set(id, entity);
156
- });
157
- return new Items(clone.values(), this.options);
158
- }
159
- page(page, pageSize) {
160
- const totalPages = Math.ceil(this.length / pageSize);
161
- return {
162
- items: this.getIds().slice(page * pageSize, (page + 1) * pageSize).map((id) => this.select(id)),
163
- page,
164
- pageSize,
165
- hasNext: page < totalPages - 1,
166
- hasPrevious: page > 0,
167
- total: this.length,
168
- totalPages
169
- };
170
- }
171
- diff(base) {
172
- return itemsDiff(base, this);
173
- }
174
- sortIds(ids, entities) {
175
- if (this.sortComparer === false) return ids;
176
- const sorter = this.sortComparer;
177
- return [...ids].sort((aId, bId) => {
178
- return sorter(entities.get(aId), entities.get(bId));
179
- });
180
- }
181
- selectId(entity) {
182
- return this.options?.selectId?.(entity) || defaultSelectId(entity);
183
- }
184
- get sortComparer() {
185
- return this.options.sortComparer || false;
186
- }
187
- [Symbol.iterator]() {
188
- return this.state.entities.values();
189
- }
190
- };
191
-
192
- //#endregion
193
- export { Items };
194
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":["selector","added: I[]","updated: ItemDiff<I, E>[]","options: ItemsOptions<I, E>"],"sources":["../src/selectId.ts","../src/selector.ts","../src/diff.ts","../src/updater.ts","../src/Items.ts"],"sourcesContent":["export type SelectId<I, E> = (entity: E) => I\n\nexport function defaultSelectId<I, E extends { id: I }>(entity: E) {\n return entity.id\n}\n","import { Items } from './Items'\n\nexport type SelectorFn<I, E> = (entity: E) => boolean\nexport type Selector<I, E> = Iterable<I> | SelectorFn<I, E>\nexport type Operation<I, E> = (entity: E | undefined, id: I) => void\n\nexport function selector<I, E>(items: Items<I, E>, selector: Selector<I, E>, operation: Operation<I, E>) {\n if (typeof selector === 'function') {\n items.getEntities().forEach((entity, id) => {\n if ((selector as SelectorFn<I, E>)(entity)) {\n operation(entity, id)\n }\n })\n } else {\n Array\n .from(selector as Iterable<I>)\n .forEach(id => operation(items.select(id), id))\n }\n}\n","import { diff } from 'ohash/utils'\nimport { Items } from './Items'\n\nexport interface ItemDiff<I, E> {\n id: I\n changes: ReturnType<typeof diff>\n}\n\nexport interface ItemsDiff<I, E> {\n added: I[]\n removed: I[]\n updated: ItemDiff<I, E>[]\n}\n\nexport function itemsDiff<I, E>(fromItems: Items<I, E>, toItems: Items<I, E>): ItemsDiff<I, E> {\n const ids = new Set(toItems.getIds())\n const baseIds = new Set(fromItems.getIds())\n\n const added: I[] = []\n const updated: ItemDiff<I, E>[] = []\n\n ids.forEach(id => {\n if (!baseIds.has(id)) {\n added.push(id)\n } else {\n const changes = diff(fromItems.select(id), toItems.select(id))\n\n if (changes.length > 0) {\n updated.push({ id, changes })\n }\n\n baseIds.delete(id)\n }\n })\n\n const removed = [...baseIds]\n\n return {\n added,\n removed,\n updated\n }\n}\n","export type UpdateFn<E> = (entity: E) => E\nexport type Updater<I, E> = UpdateFn<E> | Partial<E>\n\nexport function update<I, E>(entity: E, updater: Updater<I, E>) {\n return { ...entity, ...(typeof updater === 'function' ? updater(entity) : updater) }\n}\n","import { defaultSelectId, SelectId } from './selectId'\nimport { selector, Selector, SelectorFn } from './selector'\nimport { Updater } from './updater'\nimport { itemsDiff } from './diff'\nimport { update } from './updater'\n\nexport interface ItemsOptions<I, E> {\n selectId?: SelectId<I, E>\n sortComparer?: false | ((a: E, b: E) => number)\n}\n\nexport interface ItemsState<I, E> {\n ids: I[]\n entities: Map<I, E>\n}\n\nexport class Items<I, E> {\n private state: ItemsState<I, E>\n\n constructor(\n items: Iterable<E> = [],\n private options: ItemsOptions<I, E> = {}\n ) {\n const entities = new Map(\n Array\n .from(items)\n .map((item) => {\n const id = this.selectId(item)\n return [id, item]\n })\n )\n\n this.state = {\n ids: this.sortIds([...entities.keys()], entities),\n entities\n }\n }\n\n getIds(): I[] {\n return [...this.state.ids]\n }\n\n getEntities(): Map<I, E> {\n return new Map(this.state.entities)\n }\n\n get length(): number {\n return this.state.ids.length\n }\n\n select(id: I): E | undefined {\n return this.state.entities.get(id)\n }\n\n insert(entity: E) {\n return this.insertMany([entity])\n }\n\n insertMany(entities: Iterable<E>) {\n return new Items([\n ...this,\n ...Array.from(entities).filter(entity => !this.has(this.selectId(entity)))\n ], this.options)\n }\n\n upsert(entity: E) {\n return this.upsertMany([entity])\n }\n\n upsertMany(entities: Iterable<E>) {\n const clone = this.getEntities()\n Array.from(entities).forEach(entity => {\n const id = this.selectId(entity)\n const existing = clone.get(id)\n if (existing) {\n clone.set(id, { ...existing, ...entity })\n } else {\n clone.set(id, entity)\n }\n })\n return new Items(clone.values(), this.options)\n }\n\n set(entity: E) {\n return this.setMany([entity])\n }\n\n setMany(entities: Iterable<E>) {\n return new Items([\n ...this,\n ...entities\n ], this.options)\n }\n\n every(check: SelectorFn<I, E>) {\n return this.getIds().every(id => check(this.select(id)!))\n }\n\n some(check: SelectorFn<I, E>) {\n return this.getIds().some(id => check(this.select(id)!))\n }\n\n has(id: I) {\n return this.state.ids.includes(id)\n }\n\n hasMany(select: Selector<I, E>) {\n let failToFind = false\n let result = false\n selector(this, select, (entity) => {\n if (entity) {\n result = true\n } else {\n failToFind = true\n }\n })\n return !failToFind && result\n }\n\n update(id: I, updater: Updater<I, E>) {\n const entity = this.select(id)\n if (!entity) {\n return this\n }\n const clone = this.getEntities()\n clone.set(id, update(entity, updater))\n return new Items(clone.values(), this.options)\n }\n\n updateMany(select: Selector<I, E>, updater: Updater<I, E>) {\n const clone = this.getEntities()\n selector(this, select, (entity, id) => {\n if (entity) {\n clone.set(id, update(entity, updater))\n }\n })\n return new Items(clone.values(), this.options)\n }\n\n remove(id: I) {\n const clone = this.getEntities()\n clone.delete(id)\n return new Items(clone.values(), this.options)\n }\n\n removeMany(select: Selector<I, E>) {\n const clone = this.getEntities()\n selector(this, select, (_, id) => {\n clone.delete(id)\n })\n return new Items(clone.values(), this.options)\n }\n\n clear(): Items<I, E> {\n return new Items([], this.options)\n }\n\n filter(select: Selector<I, E>) {\n const clone = new Map<I, E>()\n\n selector(this, select, (entity, id) => {\n if (entity) {\n clone.set(id, entity)\n }\n })\n\n return new Items(clone.values(), this.options)\n }\n\n page(page: number, pageSize: number) {\n const totalPages = Math.ceil(this.length / pageSize)\n return {\n items: this.getIds()\n .slice(page * pageSize, (page + 1) * pageSize)\n .map(id => this.select(id)!),\n page,\n pageSize,\n hasNext: page < totalPages - 1,\n hasPrevious: page > 0,\n total: this.length,\n totalPages\n }\n }\n\n diff(base: Items<I, E>) {\n return itemsDiff(base, this)\n }\n\n private sortIds(\n ids: I[],\n entities: Map<I, E>\n ): Array<I> {\n if (this.sortComparer === false) {\n return ids\n }\n const sorter = this.sortComparer\n return [...ids].sort((aId, bId) => {\n const a = entities.get(aId)!\n const b = entities.get(bId)!\n return sorter(a, b)\n })\n }\n\n private selectId(entity: E): I {\n return this.options?.selectId?.(entity) || defaultSelectId(entity as E & { id: I })\n }\n\n private get sortComparer() {\n return this.options.sortComparer || false\n }\n\n [Symbol.iterator](): Iterator<E> {\n return this.state.entities.values()\n }\n}\n"],"mappings":"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"}