@arcote.tech/arc 0.0.21 → 0.0.23
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/collection/collection.d.ts +8 -6
- package/dist/collection/queries/abstract-many-items.d.ts +1 -1
- package/dist/data-storage/data-storage-forked.d.ts +1 -1
- package/dist/data-storage/data-storage.abstract.d.ts +1 -1
- package/dist/data-storage/store-state-fork.d.ts +1 -1
- package/dist/data-storage/store-state.abstract.d.ts +1 -1
- package/dist/db/interface.d.ts +15 -1
- package/dist/index.js +17 -25
- package/dist/tests/query-notification-optimization.test.d.ts +2 -0
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import type { ArcIdAny } from "../elements/id";
|
|
|
3
3
|
import { type ArcObjectAny } from "../elements/object";
|
|
4
4
|
import { objectUtil, type DeepPartial, type util } from "../utils";
|
|
5
5
|
import type { DataStorage } from "../data-storage";
|
|
6
|
+
import type { IndexQueryArgument } from "../db";
|
|
6
7
|
import { ArcAllItemsQueryBuilder } from "./query-builders/all-items";
|
|
7
8
|
import { ArcIndexedItemsQueryBuilder } from "./query-builders/indexed";
|
|
8
9
|
import { ArcOneItemQueryBuilder } from "./query-builders/one-item";
|
|
@@ -27,6 +28,11 @@ type CollectionCommandContext<Id extends ArcIdAny, Schema extends ArcObjectAny>
|
|
|
27
28
|
edit: (id: util.GetType<Id>, editCallback: (item: Deserialize<Id, Schema>) => Promise<void> | void) => Promise<void>;
|
|
28
29
|
modify: (id: util.GetType<Id>, data: objectUtil.addQuestionMarks<DeepPartial<util.FirstArgument<Schema["serialize"]>>>) => Promise<any>;
|
|
29
30
|
};
|
|
31
|
+
type IndexValue<Schema extends ArcObjectAny, Indexes extends keyof ReturnType<Schema["deserialize"]>, I extends {
|
|
32
|
+
[name: string]: Indexes[];
|
|
33
|
+
}, func extends keyof I> = {
|
|
34
|
+
[Key in I[func][number]]: util.GetType<Schema>[Key];
|
|
35
|
+
};
|
|
30
36
|
export declare class ArcCollection<Name extends string, Id extends ArcIdAny, Schema extends ArcObjectAny> extends ArcContextElement<{
|
|
31
37
|
type: "delete";
|
|
32
38
|
from: CollectionItem<ArcCollection<Name, Id, Schema>>;
|
|
@@ -68,14 +74,10 @@ export declare class ArcIndexedCollection<Name extends string, Id extends ArcIdA
|
|
|
68
74
|
readonly indexes: I;
|
|
69
75
|
constructor(name: Name, id: Id, schema: Schema, options: ArcCollectionOptions<Id, Schema>, indexes: I);
|
|
70
76
|
commandContext(dataStorage: DataStorage, publishEvent: (event: this["$event"]) => Promise<void>): CollectionCommandContext<Id, Schema> & {
|
|
71
|
-
[func in keyof I]: (args:
|
|
72
|
-
[Key in I[func][number]]: util.GetType<Schema>[Key];
|
|
73
|
-
}) => Deserialize<Id, Schema>[];
|
|
77
|
+
[func in keyof I]: (args: IndexValue<Schema, Indexes, I, func>) => Deserialize<Id, Schema>[];
|
|
74
78
|
};
|
|
75
79
|
queryBuilder(): CollectionQueryBuilder<ArcCollection<Name, Id, Schema>> & {
|
|
76
|
-
[func in keyof I]: (args:
|
|
77
|
-
[Key in I[func][number]]: util.GetType<Schema>[Key];
|
|
78
|
-
}) => ArcIndexedItemsQueryBuilder<ArcIndexedCollection<Name, Id, Schema, Indexes, I>>;
|
|
80
|
+
[func in keyof I]: (args: objectUtil.simplify<IndexQueryArgument<objectUtil.simplify<IndexValue<Schema, Indexes, I, func>>>>) => ArcIndexedItemsQueryBuilder<ArcIndexedCollection<Name, Id, Schema, Indexes, I>>;
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
83
|
export type ArcCollectionAny = ArcCollection<any, any, any>;
|
|
@@ -5,7 +5,7 @@ import { ArcCollectionQuery } from "./abstract-collection-query";
|
|
|
5
5
|
export declare class QueryCollectionResult<C extends ArcCollectionAny> {
|
|
6
6
|
private result;
|
|
7
7
|
constructor(result: CollectionItem<C>[]);
|
|
8
|
-
get(id: util.GetType<C["id"]>): ({
|
|
8
|
+
get(id: util.GetType<C["id"]> | null): ({
|
|
9
9
|
_id: string;
|
|
10
10
|
} & ReturnType<C["deserialize"]> extends infer T ? { [KeyType in keyof T]: ({
|
|
11
11
|
_id: string;
|
|
@@ -9,7 +9,7 @@ export declare class ForkedDataStorage extends DataStorage {
|
|
|
9
9
|
getReadWriteTransaction(): Promise<ReadWriteTransaction>;
|
|
10
10
|
getStore<Item extends {
|
|
11
11
|
_id: string;
|
|
12
|
-
}>(storeName: string
|
|
12
|
+
}>(storeName: string): StoreState<Item>;
|
|
13
13
|
fork(): ForkedDataStorage;
|
|
14
14
|
merge(): Promise<void>;
|
|
15
15
|
}
|
|
@@ -5,7 +5,7 @@ import type { StoreState } from "./store-state.abstract";
|
|
|
5
5
|
export declare abstract class DataStorage {
|
|
6
6
|
abstract getStore<Item extends {
|
|
7
7
|
_id: string;
|
|
8
|
-
}>(storeName: string
|
|
8
|
+
}>(storeName: string): StoreState<Item>;
|
|
9
9
|
abstract fork(): ForkedDataStorage;
|
|
10
10
|
abstract getReadTransaction(): Promise<ReadTransaction>;
|
|
11
11
|
abstract getReadWriteTransaction(): Promise<ReadWriteTransaction>;
|
|
@@ -6,7 +6,7 @@ export declare class ForkedStoreState<Item extends {
|
|
|
6
6
|
master: StoreState<Item>;
|
|
7
7
|
protected changedItems: Map<string, Item | null>;
|
|
8
8
|
changes: StoreStateChange<Item>[];
|
|
9
|
-
constructor(storeName: string, dataStorage: DataStorage, master: StoreState<Item
|
|
9
|
+
constructor(storeName: string, dataStorage: DataStorage, master: StoreState<Item>);
|
|
10
10
|
applyChangeAndReturnEvent(change: StoreStateChange<Item>): Promise<{
|
|
11
11
|
from: Item | null;
|
|
12
12
|
to: Item | null;
|
|
@@ -5,7 +5,7 @@ export declare abstract class StoreState<Item extends {
|
|
|
5
5
|
}> {
|
|
6
6
|
storeName: string;
|
|
7
7
|
protected dataStorage: DataStorage;
|
|
8
|
-
|
|
8
|
+
deserialize?: ((data: any) => Item) | undefined;
|
|
9
9
|
protected listeners: Map<QueryListenerCallback<Item>, QueryListener<Item>>;
|
|
10
10
|
constructor(storeName: string, dataStorage: DataStorage, deserialize?: ((data: any) => Item) | undefined);
|
|
11
11
|
abstract applyChange(change: StoreStateChange<Item>): Promise<{
|
package/dist/db/interface.d.ts
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
1
|
import type { ArcContextAny } from "../context";
|
|
2
|
+
export type IndexQueryArgument<T> = T | ({
|
|
3
|
+
$gt?: T;
|
|
4
|
+
$gte?: T;
|
|
5
|
+
$lt?: T;
|
|
6
|
+
$lte?: T;
|
|
7
|
+
} & ({
|
|
8
|
+
$gt: T;
|
|
9
|
+
} | {
|
|
10
|
+
$gte: T;
|
|
11
|
+
} | {
|
|
12
|
+
$lt: T;
|
|
13
|
+
} | {
|
|
14
|
+
$lte: T;
|
|
15
|
+
}));
|
|
2
16
|
export interface ReadTransaction {
|
|
3
17
|
findById(store: string, id: any): Promise<any | undefined>;
|
|
4
|
-
findByIndex(store: string, index: string, data: any): Promise<any[]>;
|
|
18
|
+
findByIndex(store: string, index: string, data: IndexQueryArgument<any>): Promise<any[]>;
|
|
5
19
|
findAll(store: string): Promise<any[]>;
|
|
6
20
|
}
|
|
7
21
|
export interface ReadWriteTransaction extends ReadTransaction {
|
package/dist/index.js
CHANGED
|
@@ -55,7 +55,7 @@ class QueryCollectionResult {
|
|
|
55
55
|
this.result = result;
|
|
56
56
|
}
|
|
57
57
|
get(id) {
|
|
58
|
-
return this.result.find((r) => r._id === id);
|
|
58
|
+
return id ? this.result.find((r) => r._id === id) : undefined;
|
|
59
59
|
}
|
|
60
60
|
map(callbackfn) {
|
|
61
61
|
return this.result.map(callbackfn);
|
|
@@ -358,7 +358,7 @@ class ArcIndexedCollection extends ArcCollection {
|
|
|
358
358
|
if (!(name in this.indexes)) {
|
|
359
359
|
throw new Error(`Index "${name}" not found in collection "${this.name}"`);
|
|
360
360
|
}
|
|
361
|
-
return (data) => dataStorage.getStore(this.name
|
|
361
|
+
return (data) => dataStorage.getStore(this.name).findByIndex(name, data);
|
|
362
362
|
}
|
|
363
363
|
});
|
|
364
364
|
}
|
|
@@ -490,7 +490,7 @@ class StoreState {
|
|
|
490
490
|
this.deserialize = deserialize;
|
|
491
491
|
}
|
|
492
492
|
fork() {
|
|
493
|
-
return new ForkedStoreState(this.storeName, this.dataStorage, this
|
|
493
|
+
return new ForkedStoreState(this.storeName, this.dataStorage, this);
|
|
494
494
|
}
|
|
495
495
|
async set(item) {
|
|
496
496
|
const change = {
|
|
@@ -543,8 +543,8 @@ class ForkedStoreState extends StoreState {
|
|
|
543
543
|
master;
|
|
544
544
|
changedItems = new Map;
|
|
545
545
|
changes = [];
|
|
546
|
-
constructor(storeName, dataStorage, master
|
|
547
|
-
super(storeName, dataStorage, deserialize);
|
|
546
|
+
constructor(storeName, dataStorage, master) {
|
|
547
|
+
super(storeName, dataStorage, master.deserialize);
|
|
548
548
|
this.master = master;
|
|
549
549
|
}
|
|
550
550
|
async applyChangeAndReturnEvent(change) {
|
|
@@ -677,11 +677,11 @@ class ForkedDataStorage extends DataStorage {
|
|
|
677
677
|
getReadWriteTransaction() {
|
|
678
678
|
return this.master.getReadWriteTransaction();
|
|
679
679
|
}
|
|
680
|
-
getStore(storeName
|
|
680
|
+
getStore(storeName) {
|
|
681
681
|
if (this.stores.has(storeName))
|
|
682
682
|
return this.stores.get(storeName);
|
|
683
|
-
const masterStorage = this.master.getStore(storeName
|
|
684
|
-
const storage = new ForkedStoreState(storeName, this, masterStorage
|
|
683
|
+
const masterStorage = this.master.getStore(storeName);
|
|
684
|
+
const storage = new ForkedStoreState(storeName, this, masterStorage);
|
|
685
685
|
this.stores.set(storeName, storage);
|
|
686
686
|
return storage;
|
|
687
687
|
}
|
|
@@ -786,6 +786,8 @@ class MasterStoreState extends StoreState {
|
|
|
786
786
|
}
|
|
787
787
|
}
|
|
788
788
|
async findById(id, listener) {
|
|
789
|
+
if (!id)
|
|
790
|
+
return;
|
|
789
791
|
if (listener)
|
|
790
792
|
this.listeners.set(listener, { callback: listener, id });
|
|
791
793
|
if (this.items.has(id))
|
|
@@ -1240,28 +1242,18 @@ class RTCClient {
|
|
|
1240
1242
|
}
|
|
1241
1243
|
const { results, syncDate } = await response.json();
|
|
1242
1244
|
const pendingStoreChanges = [];
|
|
1245
|
+
const transaction = await this.storage.getReadWriteTransaction();
|
|
1243
1246
|
for (const { store, items } of results) {
|
|
1244
1247
|
this.syncProgressCallback?.({ store, size: items.length });
|
|
1245
|
-
const
|
|
1246
|
-
if (!storeState) {
|
|
1247
|
-
console.error(`Store ${store} not found`);
|
|
1248
|
-
continue;
|
|
1249
|
-
}
|
|
1250
|
-
const changes = items.map((item) => {
|
|
1248
|
+
for (const item of items) {
|
|
1251
1249
|
if (item.deleted) {
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
};
|
|
1250
|
+
await transaction.remove(store, item._id);
|
|
1251
|
+
} else {
|
|
1252
|
+
await transaction.set(store, item);
|
|
1256
1253
|
}
|
|
1257
|
-
|
|
1258
|
-
type: "set",
|
|
1259
|
-
data: item
|
|
1260
|
-
};
|
|
1261
|
-
});
|
|
1262
|
-
pendingStoreChanges.push(storeState.applyChanges(changes));
|
|
1254
|
+
}
|
|
1263
1255
|
}
|
|
1264
|
-
await
|
|
1256
|
+
await transaction.commit();
|
|
1265
1257
|
const stateStorage = this.storage.getStore("state");
|
|
1266
1258
|
await stateStorage.applyChanges([
|
|
1267
1259
|
{
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"version": "0.0.
|
|
7
|
+
"version": "0.0.23",
|
|
8
8
|
"private": false,
|
|
9
9
|
"author": "Przemysław Krasiński [arcote.tech]",
|
|
10
10
|
"description": "Arc is a framework designed to align code closely with business logic, streamlining development and enhancing productivity.",
|