@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<Element extends E[number]>(name: Element["name"]): Element;
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 type { DatabaseAgnosticColumnInfo } from "../database/database-store";
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
- properties[key] = element.toJsonSchema?.() ?? {};
422
- if (!(element instanceof ArcOptional)) {
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
- const existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
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
- const existing = await transaction.find(this.storeName, { where: { _id: change.id } }).then((results) => results[0]);
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 { event: event3, from, to } = await this.applyChangeAndReturnEvent(transaction, change);
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.9",
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.",