@arcote.tech/arc 0.1.10 → 0.1.11
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.
|
@@ -21,11 +21,15 @@ export type ArcCommandContext<E extends ArcContextElementAny[]> = ArcContextElem
|
|
|
21
21
|
export type RemoveFalseAndResolvedPromiseFromArray<T extends any[]> = T extends [infer First, ...infer Rest] ? First extends false ? RemoveFalseAndResolvedPromiseFromArray<Rest> : First extends Promise<{
|
|
22
22
|
default: infer Inner;
|
|
23
23
|
}> ? RemoveFalseAndResolvedPromiseFromArray<[Inner, ...Rest]> : [First, ...RemoveFalseAndResolvedPromiseFromArray<Rest>] : [];
|
|
24
|
+
export type FindElementByName<E extends ArcContextElementAny[], Name extends string> = E extends [
|
|
25
|
+
infer First extends ArcContextElementAny,
|
|
26
|
+
...infer Rest extends ArcContextElementAny[]
|
|
27
|
+
] ? First["name"] extends Name ? First : FindElementByName<Rest, Name> : never;
|
|
24
28
|
export declare class ArcContext<const E extends ArcContextElementAny[]> {
|
|
25
29
|
readonly elements: E;
|
|
26
30
|
private elementsSet;
|
|
27
31
|
constructor(elements: E);
|
|
28
|
-
get<
|
|
32
|
+
get<Name extends E[number]["name"]>(name: Name): FindElementByName<E, Name>;
|
|
29
33
|
getSyncListeners(eventType: string, authContext: AuthContext): EventListener<any>[];
|
|
30
34
|
getAsyncListeners(eventType: string, authContext: AuthContext): EventListener<any>[];
|
|
31
35
|
pipe<const NewElements extends (ArcContextElementAny | false | Promise<{
|
|
@@ -6,7 +6,7 @@ export declare class MasterStoreState<Item extends {
|
|
|
6
6
|
_id: string;
|
|
7
7
|
}> extends StoreState<Item> {
|
|
8
8
|
constructor(storeName: string, dataStorage: DataStorage, deserialize?: (data: any) => Item);
|
|
9
|
-
applyChangeAndReturnEvent(transaction: ReadWriteTransaction, change: StoreStateChange<Item>): Promise<{
|
|
9
|
+
applyChangeAndReturnEvent(transaction: ReadWriteTransaction, change: StoreStateChange<Item>, transactionCache?: Map<string, Item>): Promise<{
|
|
10
10
|
from: Item | null;
|
|
11
11
|
to: Item | null;
|
|
12
12
|
event: ListenerEvent<Item>;
|
|
@@ -2,6 +2,7 @@ import type { DatabaseAgnosticColumnInfo } from "../database/database-store";
|
|
|
2
2
|
import { type objectUtil, type util } from "../utils";
|
|
3
3
|
import { ArcAbstract, type Validators } from "./abstract";
|
|
4
4
|
import type { ArcElement } from "./element";
|
|
5
|
+
import { ArcOptional } from "./optional";
|
|
5
6
|
export declare type ArcRawShape = {
|
|
6
7
|
[k: string]: ArcElement;
|
|
7
8
|
};
|
|
@@ -64,13 +65,19 @@ export declare class ArcObject<E extends ArcRawShape, V extends Validators = [
|
|
|
64
65
|
pick<Keys extends keyof E>(...keys: Keys[]): ArcObject<Pick<E, Keys>, V>;
|
|
65
66
|
omit<Keys extends keyof E>(...keys: Keys[]): ArcObject<Omit<E, Keys>, V>;
|
|
66
67
|
entries(): [string, ArcElement][];
|
|
68
|
+
keys(): (keyof E)[];
|
|
67
69
|
toJsonSchema(): any;
|
|
68
70
|
/** Generate database-agnostic column information */
|
|
69
71
|
getColumnData(): DatabaseAgnosticColumnInfo;
|
|
70
72
|
/** Merge this ArcObject with another shape */
|
|
71
73
|
merge<OtherShape extends ArcRawShape>(otherShape: OtherShape): ArcObject<E & OtherShape, V>;
|
|
74
|
+
/** Create a partial version of this ArcObject where all fields are optional */
|
|
75
|
+
partial(): ArcObjectPartial<this>;
|
|
72
76
|
}
|
|
73
77
|
export type ArcObjectAny = ArcObject<any, any>;
|
|
78
|
+
export type ArcObjectPartial<T extends ArcObjectAny> = T extends ArcObject<infer E, infer V> ? ArcObject<{
|
|
79
|
+
[K in keyof E]: ArcOptional<E[K]>;
|
|
80
|
+
}, V> : never;
|
|
74
81
|
export type ArcObjectKeys<T extends ArcObjectAny> = T extends ArcObject<infer E, any> ? Exclude<keyof E, symbol> : never;
|
|
75
82
|
export type ArcObjectValueByKey<T extends ArcObjectAny, K extends ArcObjectKeys<T>> = T extends ArcObject<infer E, any> ? E[K] : never;
|
|
76
83
|
export type ArcRawShapeType<Shape extends ArcRawShape> = {
|
package/dist/index.js
CHANGED
|
@@ -414,6 +414,9 @@ class ArcObject extends ArcAbstract {
|
|
|
414
414
|
entries() {
|
|
415
415
|
return Object.entries(this.rawShape);
|
|
416
416
|
}
|
|
417
|
+
keys() {
|
|
418
|
+
return Object.keys(this.rawShape);
|
|
419
|
+
}
|
|
417
420
|
toJsonSchema() {
|
|
418
421
|
const properties = {};
|
|
419
422
|
const required = [];
|
|
@@ -450,6 +453,13 @@ class ArcObject extends ArcAbstract {
|
|
|
450
453
|
const mergedShape = { ...this.rawShape, ...otherShape };
|
|
451
454
|
return new ArcObject(mergedShape);
|
|
452
455
|
}
|
|
456
|
+
partial() {
|
|
457
|
+
const partialShape = Object.fromEntries(Object.entries(this.rawShape).map(([key, element]) => [
|
|
458
|
+
key,
|
|
459
|
+
element instanceof ArcOptional ? element : new ArcOptional(element)
|
|
460
|
+
]));
|
|
461
|
+
return new ArcObject(partialShape);
|
|
462
|
+
}
|
|
453
463
|
}
|
|
454
464
|
function object(element) {
|
|
455
465
|
return new ArcObject(element);
|
|
@@ -2131,10 +2141,13 @@ class MasterStoreState extends StoreState {
|
|
|
2131
2141
|
constructor(storeName, dataStorage, deserialize) {
|
|
2132
2142
|
super(storeName, dataStorage, deserialize);
|
|
2133
2143
|
}
|
|
2134
|
-
async applyChangeAndReturnEvent(transaction, change) {
|
|
2144
|
+
async applyChangeAndReturnEvent(transaction, change, transactionCache) {
|
|
2135
2145
|
if (change.type === "set") {
|
|
2136
2146
|
await transaction.set(this.storeName, change.data);
|
|
2137
2147
|
const item = this.deserialize ? this.deserialize(change.data) : change.data;
|
|
2148
|
+
if (transactionCache) {
|
|
2149
|
+
transactionCache.set(change.data._id, item);
|
|
2150
|
+
}
|
|
2138
2151
|
return {
|
|
2139
2152
|
from: null,
|
|
2140
2153
|
to: item,
|
|
@@ -2158,10 +2171,18 @@ class MasterStoreState extends StoreState {
|
|
|
2158
2171
|
};
|
|
2159
2172
|
}
|
|
2160
2173
|
if (change.type === "modify") {
|
|
2161
|
-
|
|
2174
|
+
let existing;
|
|
2175
|
+
if (transactionCache && transactionCache.has(change.id)) {
|
|
2176
|
+
existing = transactionCache.get(change.id);
|
|
2177
|
+
} else {
|
|
2178
|
+
existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
|
|
2179
|
+
}
|
|
2162
2180
|
const updated = existing ? deepMerge(existing, change.data) : { _id: change.id, ...change.data };
|
|
2163
2181
|
await transaction.set(this.storeName, updated);
|
|
2164
2182
|
const item = this.deserialize ? this.deserialize(updated) : updated;
|
|
2183
|
+
if (transactionCache) {
|
|
2184
|
+
transactionCache.set(change.id, item);
|
|
2185
|
+
}
|
|
2165
2186
|
return {
|
|
2166
2187
|
from: null,
|
|
2167
2188
|
to: item,
|
|
@@ -2173,10 +2194,18 @@ class MasterStoreState extends StoreState {
|
|
|
2173
2194
|
};
|
|
2174
2195
|
}
|
|
2175
2196
|
if (change.type === "mutate") {
|
|
2176
|
-
|
|
2197
|
+
let existing;
|
|
2198
|
+
if (transactionCache && transactionCache.has(change.id)) {
|
|
2199
|
+
existing = transactionCache.get(change.id);
|
|
2200
|
+
} else {
|
|
2201
|
+
existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
|
|
2202
|
+
}
|
|
2177
2203
|
const updated = apply2(existing || {}, change.patches);
|
|
2178
2204
|
await transaction.set(this.storeName, updated);
|
|
2179
2205
|
const item = this.deserialize ? this.deserialize(updated) : updated;
|
|
2206
|
+
if (transactionCache) {
|
|
2207
|
+
transactionCache.set(change.id, item);
|
|
2208
|
+
}
|
|
2180
2209
|
return {
|
|
2181
2210
|
from: null,
|
|
2182
2211
|
to: item,
|
|
@@ -2191,16 +2220,18 @@ class MasterStoreState extends StoreState {
|
|
|
2191
2220
|
}
|
|
2192
2221
|
async applyChange(change) {
|
|
2193
2222
|
const transaction = await this.dataStorage.getReadWriteTransaction();
|
|
2194
|
-
const
|
|
2223
|
+
const transactionCache = new Map;
|
|
2224
|
+
const { event: event3, from, to } = await this.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
2195
2225
|
await transaction.commit();
|
|
2196
2226
|
this.notifyListeners([event3]);
|
|
2197
2227
|
return { from, to };
|
|
2198
2228
|
}
|
|
2199
2229
|
async applyChanges(changes) {
|
|
2200
2230
|
const transaction = await this.dataStorage.getReadWriteTransaction();
|
|
2231
|
+
const transactionCache = new Map;
|
|
2201
2232
|
const events = [];
|
|
2202
2233
|
for (const change of changes) {
|
|
2203
|
-
const { event: event3 } = await this.applyChangeAndReturnEvent(transaction, change);
|
|
2234
|
+
const { event: event3 } = await this.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
2204
2235
|
if (event3)
|
|
2205
2236
|
events.push(event3);
|
|
2206
2237
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcote.tech/arc",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.11",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Przemysław Krasiński [arcote.tech]",
|
|
7
7
|
"description": "Arc is a framework designed to align code closely with business logic, streamlining development and enhancing productivity.",
|