@arcote.tech/arc 0.1.9 → 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>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { DatabaseAgnosticColumnInfo } from "../database/database-store";
|
|
1
2
|
import { type objectUtil, type util } from "../utils";
|
|
2
3
|
import { ArcAbstract, type Validators } from "./abstract";
|
|
3
4
|
import type { ArcElement } from "./element";
|
|
4
|
-
import
|
|
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,12 +414,17 @@ 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 = [];
|
|
420
423
|
for (const [key, element] of Object.entries(this.rawShape)) {
|
|
421
|
-
|
|
422
|
-
|
|
424
|
+
if (element instanceof ArcOptional) {
|
|
425
|
+
properties[key] = element.parent.toJsonSchema?.() ?? {};
|
|
426
|
+
} else {
|
|
427
|
+
properties[key] = element.toJsonSchema?.() ?? {};
|
|
423
428
|
required.push(key);
|
|
424
429
|
}
|
|
425
430
|
}
|
|
@@ -448,6 +453,13 @@ class ArcObject extends ArcAbstract {
|
|
|
448
453
|
const mergedShape = { ...this.rawShape, ...otherShape };
|
|
449
454
|
return new ArcObject(mergedShape);
|
|
450
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
|
+
}
|
|
451
463
|
}
|
|
452
464
|
function object(element) {
|
|
453
465
|
return new ArcObject(element);
|
|
@@ -2129,10 +2141,13 @@ class MasterStoreState extends StoreState {
|
|
|
2129
2141
|
constructor(storeName, dataStorage, deserialize) {
|
|
2130
2142
|
super(storeName, dataStorage, deserialize);
|
|
2131
2143
|
}
|
|
2132
|
-
async applyChangeAndReturnEvent(transaction, change) {
|
|
2144
|
+
async applyChangeAndReturnEvent(transaction, change, transactionCache) {
|
|
2133
2145
|
if (change.type === "set") {
|
|
2134
2146
|
await transaction.set(this.storeName, change.data);
|
|
2135
2147
|
const item = this.deserialize ? this.deserialize(change.data) : change.data;
|
|
2148
|
+
if (transactionCache) {
|
|
2149
|
+
transactionCache.set(change.data._id, item);
|
|
2150
|
+
}
|
|
2136
2151
|
return {
|
|
2137
2152
|
from: null,
|
|
2138
2153
|
to: item,
|
|
@@ -2156,10 +2171,18 @@ class MasterStoreState extends StoreState {
|
|
|
2156
2171
|
};
|
|
2157
2172
|
}
|
|
2158
2173
|
if (change.type === "modify") {
|
|
2159
|
-
|
|
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
|
+
}
|
|
2160
2180
|
const updated = existing ? deepMerge(existing, change.data) : { _id: change.id, ...change.data };
|
|
2161
2181
|
await transaction.set(this.storeName, updated);
|
|
2162
2182
|
const item = this.deserialize ? this.deserialize(updated) : updated;
|
|
2183
|
+
if (transactionCache) {
|
|
2184
|
+
transactionCache.set(change.id, item);
|
|
2185
|
+
}
|
|
2163
2186
|
return {
|
|
2164
2187
|
from: null,
|
|
2165
2188
|
to: item,
|
|
@@ -2171,10 +2194,18 @@ class MasterStoreState extends StoreState {
|
|
|
2171
2194
|
};
|
|
2172
2195
|
}
|
|
2173
2196
|
if (change.type === "mutate") {
|
|
2174
|
-
|
|
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
|
+
}
|
|
2175
2203
|
const updated = apply2(existing || {}, change.patches);
|
|
2176
2204
|
await transaction.set(this.storeName, updated);
|
|
2177
2205
|
const item = this.deserialize ? this.deserialize(updated) : updated;
|
|
2206
|
+
if (transactionCache) {
|
|
2207
|
+
transactionCache.set(change.id, item);
|
|
2208
|
+
}
|
|
2178
2209
|
return {
|
|
2179
2210
|
from: null,
|
|
2180
2211
|
to: item,
|
|
@@ -2189,16 +2220,18 @@ class MasterStoreState extends StoreState {
|
|
|
2189
2220
|
}
|
|
2190
2221
|
async applyChange(change) {
|
|
2191
2222
|
const transaction = await this.dataStorage.getReadWriteTransaction();
|
|
2192
|
-
const
|
|
2223
|
+
const transactionCache = new Map;
|
|
2224
|
+
const { event: event3, from, to } = await this.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
2193
2225
|
await transaction.commit();
|
|
2194
2226
|
this.notifyListeners([event3]);
|
|
2195
2227
|
return { from, to };
|
|
2196
2228
|
}
|
|
2197
2229
|
async applyChanges(changes) {
|
|
2198
2230
|
const transaction = await this.dataStorage.getReadWriteTransaction();
|
|
2231
|
+
const transactionCache = new Map;
|
|
2199
2232
|
const events = [];
|
|
2200
2233
|
for (const change of changes) {
|
|
2201
|
-
const { event: event3 } = await this.applyChangeAndReturnEvent(transaction, change);
|
|
2234
|
+
const { event: event3 } = await this.applyChangeAndReturnEvent(transaction, change, transactionCache);
|
|
2202
2235
|
if (event3)
|
|
2203
2236
|
events.push(event3);
|
|
2204
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.",
|