@arcote.tech/arc 0.1.4 → 0.1.6

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.
@@ -9,24 +9,35 @@ export declare class ArcCommand<Name extends string, Params extends ArcObjectAny
9
9
  result: Results[number];
10
10
  }, Name> {
11
11
  readonly name: Name;
12
- private _description?;
13
- private _params?;
14
- private _results?;
15
- private _elements?;
16
- private _handler?;
17
- private _isPublic;
12
+ _description?: string;
13
+ _params?: Params;
14
+ _results?: Results;
15
+ _elements?: Elements;
16
+ _handler?: ArcCommmandHandler<Elements, Params, Results> | false;
17
+ _isPublic: boolean;
18
18
  constructor(name: Name);
19
19
  use<const E extends ArcContextElementAny[]>(elements: E): ArcCommand<Name, Params, Results, E>;
20
20
  description(description: string): ArcCommand<Name, Params, Results, Elements>;
21
21
  public(): ArcCommand<Name, Params, Results, Elements>;
22
22
  get isPublic(): boolean;
23
+ matchesCommandPath(pathname: string): {
24
+ matches: boolean;
25
+ isPublic: boolean;
26
+ };
23
27
  withParams<NewParams extends ArcRawShape>(schema: NewParams | ArcObject<NewParams>): ArcCommand<Name, ArcObject<NewParams>, Results, Elements>;
24
28
  withResult<NewResults extends ArcRawShape[]>(...schemas: NewResults): ArcCommand<Name, Params, { [K in keyof NewResults]: ArcObject<NewResults[K]>; }, Elements>;
25
29
  handle(handler: ArcCommmandHandler<Elements, Params, Results> | false): ArcCommand<Name, Params, Results, Elements>;
26
30
  commandClient: (ctx: any) => (Params extends ArcObjectAny ? (params: $type<Params>) => Promise<$type<Results[number]>> : () => Promise<$type<Results[number]>>) & {
27
31
  params: Params;
28
32
  };
29
- private clone;
33
+ protected clone(): ArcCommand<Name, Params, Results, Elements>;
34
+ toJsonSchema(): {
35
+ type: string;
36
+ name: Name;
37
+ description: string | undefined;
38
+ parameters: any;
39
+ };
30
40
  }
31
41
  export declare function command<Name extends string>(name: Name): ArcCommand<Name, null, any[], any[]>;
42
+ export type ArcCommandAny = ArcCommand<any, any, any, any>;
32
43
  //# sourceMappingURL=command.d.ts.map
@@ -15,6 +15,8 @@ export type ArcContextElementMethodReturnType<Elements extends ArcContextElement
15
15
  }[number]>;
16
16
  export type ArcCommandContext<E extends ArcContextElementAny[]> = ArcContextElementMethodReturnType<E, "commandContext"> & {
17
17
  $auth: AuthContext;
18
+ } & {
19
+ get: <ArcElement extends ArcContextElementAny>(element: ArcElement) => ArcElement["commandContext"] extends infer CommandContext ? CommandContext extends (...args: any) => any ? ReturnType<CommandContext> : never : never;
18
20
  };
19
21
  export type RemoveFalseAndResolvedPromiseFromArray<T extends any[]> = T extends [infer First, ...infer Rest] ? First extends false ? RemoveFalseAndResolvedPromiseFromArray<Rest> : First extends Promise<{
20
22
  default: infer Inner;
@@ -41,8 +43,7 @@ export type ContextEvents<Context extends ArcContextAny> = {
41
43
  } & ElementEvents<Element>>;
42
44
  }[Context["elements"][number]["name"]];
43
45
  export type Listener<Context extends ArcContextAny> = (event: ContextEvents<Context>, context: CommandContext<Context>) => Promise<void> | void;
44
- export declare function context<const Elements extends (ArcContextElementAny | false | Promise<{
45
- default: ArcContextElementAny;
46
- }>)[]>(elementsPromise: Elements): Promise<ArcContext<RemoveFalseAndResolvedPromiseFromArray<Elements>>>;
46
+ export declare function context<const Elements extends ArcContextElementAny[]>(elements: Elements): ArcContext<Elements>;
47
+ export declare function contextMerge<const Contexts extends ArcContextAny[]>(...contexts: Contexts): ArcContext<Contexts[number]["elements"]>;
47
48
  export {};
48
49
  //# sourceMappingURL=context.d.ts.map
@@ -50,7 +50,7 @@ export type StoreSchema = {
50
50
  export declare abstract class ArcContextElement<const Event, const Name extends string | undefined = undefined> {
51
51
  readonly $event: Event;
52
52
  readonly name?: Name;
53
- queryBuilder?(queryContext: QueryBuilderContext, authContext: AuthContext): any;
53
+ queryBuilder?: (queryContext: QueryBuilderContext, authContext: AuthContext) => any;
54
54
  commandContext?: (dataStorage: DataStorage, publishEvent: PublishEventFunction, authContext: AuthContext) => any;
55
55
  commandClient?: (commandContext: any, authContext: AuthContext) => (...args: any[]) => any;
56
56
  observer?: (authContext: AuthContext) => Record<string, ListenerConfig>;
@@ -3,14 +3,7 @@ import { ArcObject, type ArcObjectAny, type ArcRawShape } from "../elements/obje
3
3
  import type { $type } from "../utils";
4
4
  import { ArcContextElementWithStore, type AuthContext, type AuthorizationRestrictions, type EventAuthorizationRestrictions, type StoreSchema } from "./element";
5
5
  export type EventMetadata = {
6
- occurredAt: string;
7
- createdBy?: {
8
- id: string;
9
- type: string;
10
- };
11
- source?: string;
12
- correlationId?: string;
13
- version?: number;
6
+ createdAt: Date;
14
7
  };
15
8
  export declare class ArcEvent<const Name extends string, const PayloadShape extends ArcObjectAny | undefined> extends ArcContextElementWithStore<ArcEventInstance<ArcEvent<Name, PayloadShape>>, Name> {
16
9
  readonly name: Name;
@@ -24,6 +24,10 @@ export declare abstract class ArcAbstract<V extends Validators> implements ArcEl
24
24
  name: Name;
25
25
  validator: Val;
26
26
  }]>;
27
+ /**
28
+ * Default JSON Schema representation – concrete subclasses should override where applicable.
29
+ */
30
+ toJsonSchema(): any;
27
31
  getValidations(): V;
28
32
  }
29
33
  export type ArcAbstractAny = ArcAbstract<any>;
@@ -0,0 +1,10 @@
1
+ import { ArcAbstract, type Validators } from "./abstract";
2
+ export declare class ArcAny<T, V extends Validators = []> extends ArcAbstract<V> {
3
+ constructor();
4
+ parse(value: T): any;
5
+ serialize(value: T): any;
6
+ deserialize(value: any): T;
7
+ toJsonSchema(): {};
8
+ }
9
+ export declare function any<T extends any>(): ArcAny<T, any>;
10
+ //# sourceMappingURL=any.d.ts.map
@@ -54,6 +54,10 @@ export declare class ArcArray<E extends ArcElement, V extends Validators = [
54
54
  name: Name;
55
55
  validator: Fn;
56
56
  }]>>>;
57
+ toJsonSchema(): {
58
+ type: string;
59
+ items: any;
60
+ };
57
61
  }
58
62
  export type ArcArrayAny = ArcArray<any>;
59
63
  export declare function array<E extends ArcElement>(element: E): ArcArray<E, [{
@@ -67,6 +67,11 @@ export declare class ArcBlob<V extends Validators = [typeof blobValidator]> exte
67
67
  * Override parse to validate blob objects
68
68
  */
69
69
  parse(value: any): Blob;
70
+ toJsonSchema(): {
71
+ type: string;
72
+ contentEncoding: string;
73
+ contentMediaType: string;
74
+ };
70
75
  }
71
76
  export declare function blob(): ArcBlob<[{
72
77
  readonly name: "blob";
@@ -11,6 +11,9 @@ export declare class ArcBoolean<V extends Validators> extends ArcPrimitive<V, bo
11
11
  name: Name;
12
12
  validator: Fn;
13
13
  }]>>>;
14
+ toJsonSchema(): {
15
+ type: string;
16
+ };
14
17
  }
15
18
  export declare function boolean(): ArcBoolean<Validators>;
16
19
  //# sourceMappingURL=boolean.d.ts.map
@@ -17,6 +17,7 @@ export declare class ArcBranded<E extends ArcAbstractAny, Brand extends string |
17
17
  };
18
18
  optional(): ArcOptional<this>;
19
19
  validate(value: unknown): unknown;
20
+ toJsonSchema(): any;
20
21
  }
21
22
  export type ArcBrandedAny = ArcBranded<ArcAbstractAny, any>;
22
23
  //# sourceMappingURL=branded.d.ts.map
@@ -30,6 +30,10 @@ export declare class ArcDate<V extends Validators = [typeof dateValidator]> exte
30
30
  name: Name;
31
31
  validator: Fn;
32
32
  }]>>>;
33
+ toJsonSchema(): {
34
+ type: string;
35
+ format: string;
36
+ };
33
37
  }
34
38
  export declare function date(): ArcDate<[{
35
39
  name: "type";
@@ -8,5 +8,6 @@ export declare class ArcDefault<E extends ArcElement> implements ArcElement {
8
8
  parse(value: util.FirstArgument<E["parse"]> | undefined): ReturnType<E["parse"]>;
9
9
  serialize(value: util.FirstArgument<E["serialize"]> | undefined): ReturnType<E["serialize"]>;
10
10
  deserialize(value: util.FirstArgument<E["deserialize"]> | undefined): ReturnType<E["deserialize"]>;
11
+ toJsonSchema(): any;
11
12
  }
12
13
  //# sourceMappingURL=default.d.ts.map
@@ -3,5 +3,9 @@ export interface ArcElement {
3
3
  deserialize(value: unknown): unknown;
4
4
  parse(value: unknown): unknown;
5
5
  validate(value: unknown): unknown;
6
+ /**
7
+ * Returns JSON Schema Draft-07 representation of this element.
8
+ */
9
+ toJsonSchema(): any;
6
10
  }
7
11
  //# sourceMappingURL=element.d.ts.map
@@ -127,6 +127,11 @@ export declare class ArcFile<V extends Validators = [typeof fileValidator]> exte
127
127
  * Override parse to validate file objects
128
128
  */
129
129
  parse(value: any): File;
130
+ toJsonSchema(): {
131
+ type: string;
132
+ contentEncoding: string;
133
+ contentMediaType: string;
134
+ };
130
135
  }
131
136
  export declare function file(): ArcFile<[{
132
137
  readonly name: "file";
@@ -1,3 +1,4 @@
1
+ export * from "./any";
1
2
  export * from "./array";
2
3
  export * from "./blob";
3
4
  export * from "./boolean";
@@ -27,6 +27,9 @@ export declare class ArcNumber<V extends Validators = [typeof numberValidator]>
27
27
  name: Name;
28
28
  validator: Fn;
29
29
  }]>>>;
30
+ toJsonSchema(): {
31
+ type: string;
32
+ };
30
33
  }
31
34
  export declare function number(): ArcNumber<[{
32
35
  name: "type";
@@ -63,6 +63,7 @@ export declare class ArcObject<E extends ArcRawShape, V extends Validators = [
63
63
  pick<Keys extends keyof E>(...keys: Keys[]): ArcObject<Pick<E, Keys>, V>;
64
64
  omit<Keys extends keyof E>(...keys: Keys[]): ArcObject<Omit<E, Keys>, V>;
65
65
  entries(): [string, ArcElement][];
66
+ toJsonSchema(): any;
66
67
  }
67
68
  export type ArcObjectAny = ArcObject<any, any>;
68
69
  export type ArcObjectKeys<T extends ArcObjectAny> = T extends ArcObject<infer E, any> ? Exclude<keyof E, symbol> : never;
@@ -80,5 +81,9 @@ export declare function object<E extends ArcRawShape>(element: E): ArcObject<E,
80
81
  name: "schema";
81
82
  validator: (value: any) => false | { [key in keyof E]: ReturnType<E[key]["validate"]>; };
82
83
  }]>;
84
+ export type ArcObjectMerge<A extends ArcObjectAny, B extends ArcObjectAny> = [A, B] extends [
85
+ ArcObject<infer AShape, infer AValidators>,
86
+ ArcObject<infer BShape, infer BValidators>
87
+ ] ? ArcObject<AShape & BShape, [...AValidators, ...BValidators]> : never;
83
88
  export {};
84
89
  //# sourceMappingURL=object.d.ts.map
@@ -8,6 +8,9 @@ export declare class ArcOptional<E extends ArcElement> implements ArcElement {
8
8
  serialize(value: util.FirstArgument<E["serialize"]> | null | undefined): ReturnType<E["serialize"]> | null;
9
9
  deserialize(value: util.FirstArgument<E["deserialize"]> | null | undefined): ReturnType<E["deserialize"]> | null;
10
10
  validate(value: unknown): unknown;
11
+ toJsonSchema(): {
12
+ anyOf: any[];
13
+ };
11
14
  }
12
15
  export type ArcOptionalAny = ArcOptional<ArcAbstractAny>;
13
16
  //# sourceMappingURL=optional.d.ts.map
@@ -1,2 +1,37 @@
1
- export {};
1
+ import { type util } from "../utils";
2
+ import type { ArcElement } from "./element";
3
+ /**
4
+ * ArcOr allows you to create a union schema from existing Arc elements.
5
+ * The generic parameter keeps the type-information of every provided
6
+ * element which results in a **strongly-typed** union of all underlying
7
+ * element types.
8
+ */
9
+ export declare class ArcOr<T extends ArcElement[]> implements ArcElement {
10
+ private readonly elements;
11
+ constructor(elements: T);
12
+ /**
13
+ * Serialises a union value using the first matching element.
14
+ */
15
+ serialize(value: util.FirstArgument<T[number]["serialize"]>): ReturnType<T[number]["serialize"]>;
16
+ /**
17
+ * Deserialises a raw value using the first element that validates it.
18
+ */
19
+ deserialize(value: util.FirstArgument<T[number]["deserialize"]>): ReturnType<T[number]["deserialize"]>;
20
+ /**
21
+ * Parses an input value using the first element that validates it.
22
+ */
23
+ parse(value: util.FirstArgument<T[number]["parse"]>): ReturnType<T[number]["parse"]>;
24
+ /**
25
+ * Runs validation on a value against **all** underlying elements.
26
+ * Succeeds (returns `false`) when at least one element validates the value.
27
+ * Otherwise returns a map of errors keyed by the element index.
28
+ */
29
+ validate(value: unknown): unknown;
30
+ toJsonSchema(): {
31
+ anyOf: any[];
32
+ };
33
+ private pickElement;
34
+ private isTypeOf;
35
+ }
36
+ export declare function or<T extends ArcElement[]>(...elements: T): ArcOr<T>;
2
37
  //# sourceMappingURL=or.d.ts.map
@@ -19,6 +19,11 @@ export declare class ArcRecord<Key extends ArcKey, E extends ArcElement, V exten
19
19
  parse(value: Record<util.FirstArgument<Key["parse"]>, util.FirstArgument<E["parse"]>>): Record<ReturnType<Key["parse"]>, ReturnType<E["parse"]>>;
20
20
  serialize(value: Record<ReturnType<Key["serialize"]>, ReturnType<E["serialize"]>>): Record<ReturnType<Key["serialize"]>, ReturnType<E["serialize"]>>;
21
21
  deserialize(value: Record<ReturnType<Key["deserialize"]>, ReturnType<E["deserialize"]>>): Record<ReturnType<Key["deserialize"]>, ReturnType<E["deserialize"]>>;
22
+ toJsonSchema(): {
23
+ type: string;
24
+ propertyNames: any;
25
+ additionalProperties: any;
26
+ };
22
27
  }
23
28
  export type ArcRecordAny = ArcRecord<any, any>;
24
29
  export declare function record<Key extends ArcKey, E extends ArcElement>(key: Key, element: E): ArcRecord<Key, E, [{
@@ -13,6 +13,10 @@ export declare class ArcStringEnum<const T extends string[], V extends Validator
13
13
  parse<Value extends T[number]>(value: Value): Value;
14
14
  serialize<Value extends T[number]>(value: Value): Value;
15
15
  deserialize<Value extends T[number]>(value: Value): Value;
16
+ toJsonSchema(): {
17
+ readonly type: "string";
18
+ readonly enum: T;
19
+ };
16
20
  getEnumerators(): T;
17
21
  }
18
22
  export type ArcStringEnumAny = ArcStringEnum<any>;
@@ -64,6 +64,9 @@ export declare class ArcString<V extends Validators = [typeof stringValidator]>
64
64
  currentEmail: string;
65
65
  } | undefined;
66
66
  }]>;
67
+ toJsonSchema(): {
68
+ type: string;
69
+ };
67
70
  url(): ArcString<[...V, {
68
71
  name: "url";
69
72
  validator: (value: string) => {
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export * from "./db";
6
6
  export * from "./elements";
7
7
  export * from "./listener";
8
8
  export * from "./model";
9
+ export * from "./route";
9
10
  export * from "./rtc";
10
11
  export * from "./state";
11
12
  export * from "./utils";
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  class ArcContextElement {
3
3
  $event;
4
4
  name;
5
+ queryBuilder;
5
6
  commandContext;
6
7
  commandClient;
7
8
  observer;
@@ -36,6 +37,12 @@ class ArcOptional {
36
37
  return false;
37
38
  return this.parent.validate(value);
38
39
  }
40
+ toJsonSchema() {
41
+ const parentSchema = this.parent.toJsonSchema?.() ?? {};
42
+ return {
43
+ anyOf: [parentSchema, { type: "null" }]
44
+ };
45
+ }
39
46
  }
40
47
 
41
48
  // elements/branded.ts
@@ -61,6 +68,9 @@ class ArcBranded {
61
68
  validate(value) {
62
69
  return this.parent.validate(value);
63
70
  }
71
+ toJsonSchema() {
72
+ return this.parent.toJsonSchema?.() ?? {};
73
+ }
64
74
  }
65
75
 
66
76
  // elements/default.ts
@@ -93,6 +103,14 @@ class ArcDefault {
93
103
  } else
94
104
  return this.defaultValueOrCallback;
95
105
  }
106
+ toJsonSchema() {
107
+ const schema = this.parent.toJsonSchema?.() ?? {};
108
+ const defaultValue = typeof this.defaultValueOrCallback === "function" ? this.defaultValueOrCallback() : this.defaultValueOrCallback;
109
+ return {
110
+ ...schema,
111
+ default: defaultValue
112
+ };
113
+ }
96
114
  }
97
115
 
98
116
  // elements/abstract.ts
@@ -134,6 +152,9 @@ class ArcAbstract {
134
152
  newInstance.validations = [...this.validations, { name, validator }];
135
153
  return newInstance;
136
154
  }
155
+ toJsonSchema() {
156
+ return {};
157
+ }
137
158
  getValidations() {
138
159
  return this.validations;
139
160
  }
@@ -254,6 +275,9 @@ class ArcString extends ArcPrimitive {
254
275
  }
255
276
  });
256
277
  }
278
+ toJsonSchema() {
279
+ return { type: "string" };
280
+ }
257
281
  url() {
258
282
  const regex = /^(https?):\/\/(?![-0-9])(?!www\.[0-9])(?:[a-zA-Z0-9-]+(?::[a-zA-Z0-9-]+)?@)?(?:localhost|\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b|[a-zA-Z0-9-]+\.)?[a-zA-Z0-9-]+\.(?:[a-zA-Z]{2,}|[a-zA-Z]{2}\.[a-zA-Z]{2})(?::\d{1,5})?(?!\/\/)(?:\/[a-zA-Z0-9-._~:?#\[\]@!$&'()*+,;=]*)*(?!\/{2})(?:;[a-zA-Z0-9-._~:?#\[\]@!$&'()*+,;=]*)*(\?(?!=)[a-zA-Z0-9&=;]*)?(\#[a-zA-Z0-9-]*)?$|^(https?):\/\/(localhost|\b(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b)(?::\d{1,5})?(?!\/\/)(?:\/[a-zA-Z0-9-._~:?#\[\]@!$&'()*+,;=]*)*(?!\/{2})(?:;[a-zA-Z0-9-._~:?#\[\]@!$&'()*+,;=]*)*(\?(?!=)[a-zA-Z0-9&=;]*)?(\#[a-zA-Z0-9-]*)?$/;
259
283
  return this.validation("url", (value) => {
@@ -314,6 +338,27 @@ function customId(name, createFn) {
314
338
  return new ArcCustomId(name, createFn);
315
339
  }
316
340
 
341
+ // elements/any.ts
342
+ class ArcAny extends ArcAbstract {
343
+ constructor() {
344
+ super([]);
345
+ }
346
+ parse(value) {
347
+ return value;
348
+ }
349
+ serialize(value) {
350
+ return value;
351
+ }
352
+ deserialize(value) {
353
+ return value;
354
+ }
355
+ toJsonSchema() {
356
+ return {};
357
+ }
358
+ }
359
+ function any() {
360
+ return new ArcAny;
361
+ }
317
362
  // elements/object.ts
318
363
  var objectValidator = typeValidatorBuilder("object");
319
364
 
@@ -421,6 +466,23 @@ class ArcObject extends ArcAbstract {
421
466
  entries() {
422
467
  return Object.entries(this.rawShape);
423
468
  }
469
+ toJsonSchema() {
470
+ const properties = {};
471
+ const required = [];
472
+ for (const [key, element] of Object.entries(this.rawShape)) {
473
+ properties[key] = element.toJsonSchema?.() ?? {};
474
+ if (!(element instanceof ArcOptional)) {
475
+ required.push(key);
476
+ }
477
+ }
478
+ const schema = {
479
+ type: "object",
480
+ properties
481
+ };
482
+ if (required.length)
483
+ schema.required = required;
484
+ return schema;
485
+ }
424
486
  }
425
487
  function object(element) {
426
488
  return new ArcObject(element);
@@ -510,6 +572,12 @@ class ArcArray extends ArcAbstract {
510
572
  const instance = this.pipeValidation(name, validator);
511
573
  return instance;
512
574
  }
575
+ toJsonSchema() {
576
+ return {
577
+ type: "array",
578
+ items: this.parent.toJsonSchema?.() ?? {}
579
+ };
580
+ }
513
581
  }
514
582
  function array(element) {
515
583
  return new ArcArray(element);
@@ -601,6 +669,13 @@ class ArcBlob extends ArcPrimitive {
601
669
  }
602
670
  throw new Error("Expected Blob object");
603
671
  }
672
+ toJsonSchema() {
673
+ return {
674
+ type: "string",
675
+ contentEncoding: "base64",
676
+ contentMediaType: "application/octet-stream"
677
+ };
678
+ }
604
679
  }
605
680
  function blob() {
606
681
  return new ArcBlob;
@@ -619,6 +694,9 @@ class ArcBoolean extends ArcPrimitive {
619
694
  const instance = this.pipeValidation(name, validator);
620
695
  return instance;
621
696
  }
697
+ toJsonSchema() {
698
+ return { type: "boolean" };
699
+ }
622
700
  }
623
701
  function boolean() {
624
702
  return new ArcBoolean;
@@ -658,6 +736,12 @@ class ArcDate extends ArcAbstract {
658
736
  const instance = this.pipeValidation(name, validator);
659
737
  return instance;
660
738
  }
739
+ toJsonSchema() {
740
+ return {
741
+ type: "string",
742
+ format: "date-time"
743
+ };
744
+ }
661
745
  }
662
746
  function date() {
663
747
  return new ArcDate;
@@ -825,6 +909,13 @@ class ArcFile extends ArcPrimitive {
825
909
  }
826
910
  throw new Error("Expected File object");
827
911
  }
912
+ toJsonSchema() {
913
+ return {
914
+ type: "string",
915
+ contentEncoding: "base64",
916
+ contentMediaType: "application/octet-stream"
917
+ };
918
+ }
828
919
  }
829
920
  function file() {
830
921
  return new ArcFile;
@@ -852,10 +943,65 @@ class ArcNumber extends ArcPrimitive {
852
943
  const instance = this.pipeValidation(name, validator);
853
944
  return instance;
854
945
  }
946
+ toJsonSchema() {
947
+ return { type: "number" };
948
+ }
855
949
  }
856
950
  function number() {
857
951
  return new ArcNumber;
858
952
  }
953
+ // elements/or.ts
954
+ class ArcOr {
955
+ elements;
956
+ constructor(elements) {
957
+ this.elements = elements;
958
+ }
959
+ serialize(value) {
960
+ const element = this.pickElement(value);
961
+ return element.serialize(value);
962
+ }
963
+ deserialize(value) {
964
+ const element = this.pickElement(value);
965
+ return element.deserialize(value);
966
+ }
967
+ parse(value) {
968
+ const element = this.pickElement(value);
969
+ return element.parse(value);
970
+ }
971
+ validate(value) {
972
+ const errors = this.elements.reduce((acc, element, idx) => {
973
+ const err = element.validate(value);
974
+ if (err)
975
+ acc[idx] = err;
976
+ return acc;
977
+ }, {});
978
+ if (Object.keys(errors).length !== this.elements.length)
979
+ return false;
980
+ return errors;
981
+ }
982
+ toJsonSchema() {
983
+ return {
984
+ anyOf: this.elements.map((el) => el.toJsonSchema?.() ?? {})
985
+ };
986
+ }
987
+ pickElement(value) {
988
+ for (const element of this.elements) {
989
+ if (this.isTypeOf(element, value))
990
+ return element;
991
+ }
992
+ throw new Error("Unable to match value with any of the provided elements for ArcOr");
993
+ }
994
+ isTypeOf(element, value) {
995
+ try {
996
+ return element.validate(value) === false;
997
+ } catch {
998
+ return false;
999
+ }
1000
+ }
1001
+ }
1002
+ function or(...elements) {
1003
+ return new ArcOr(elements);
1004
+ }
859
1005
  // elements/record.ts
860
1006
  class ArcRecord extends ArcAbstract {
861
1007
  key;
@@ -906,6 +1052,13 @@ class ArcRecord extends ArcAbstract {
906
1052
  return acc;
907
1053
  }, {});
908
1054
  }
1055
+ toJsonSchema() {
1056
+ return {
1057
+ type: "object",
1058
+ propertyNames: this.key.toJsonSchema?.() ?? {},
1059
+ additionalProperties: this.element.toJsonSchema?.() ?? {}
1060
+ };
1061
+ }
909
1062
  }
910
1063
  function record(key, element) {
911
1064
  return new ArcRecord(key, element);
@@ -935,6 +1088,12 @@ class ArcStringEnum extends ArcAbstract {
935
1088
  deserialize(value) {
936
1089
  return value;
937
1090
  }
1091
+ toJsonSchema() {
1092
+ return {
1093
+ type: "string",
1094
+ enum: this.values
1095
+ };
1096
+ }
938
1097
  getEnumerators() {
939
1098
  return this.values;
940
1099
  }
@@ -1114,7 +1273,7 @@ class ArcFindQuery extends ArcCollectionQuery {
1114
1273
  }
1115
1274
  onChange(change) {
1116
1275
  const lastResult = this.lastResult;
1117
- const lastResultAsArray = lastResult?.toArray() || [];
1276
+ const lastResultAsArray = lastResult || [];
1118
1277
  const index = lastResultAsArray.findIndex((e) => e._id === (change.type === "delete" ? change.id : change.id));
1119
1278
  const isInLastResult = index !== -1;
1120
1279
  const shouldBeInTheResult = change.type !== "delete" && this.checkItem(change.item);
@@ -1304,6 +1463,16 @@ class ArcCommand extends ArcContextElement {
1304
1463
  get isPublic() {
1305
1464
  return this._isPublic;
1306
1465
  }
1466
+ matchesCommandPath(pathname) {
1467
+ if (!pathname.startsWith("/command/")) {
1468
+ return { matches: false, isPublic: false };
1469
+ }
1470
+ const commandName = pathname.split("/command/")[1];
1471
+ if (commandName === this.name) {
1472
+ return { matches: true, isPublic: this._isPublic };
1473
+ }
1474
+ return { matches: false, isPublic: false };
1475
+ }
1307
1476
  withParams(schema) {
1308
1477
  const clone = this.clone();
1309
1478
  clone._params = schema instanceof ArcObject ? schema : object(schema);
@@ -1335,6 +1504,18 @@ class ArcCommand extends ArcContextElement {
1335
1504
  clone._isPublic = this._isPublic;
1336
1505
  return clone;
1337
1506
  }
1507
+ toJsonSchema() {
1508
+ const parametersSchema = this._params ? this._params.toJsonSchema?.() ?? {
1509
+ type: "object",
1510
+ properties: {}
1511
+ } : { type: "object", properties: {} };
1512
+ return {
1513
+ type: "function",
1514
+ name: this.name,
1515
+ description: this._description ?? undefined,
1516
+ parameters: parametersSchema
1517
+ };
1518
+ }
1338
1519
  }
1339
1520
  function command(name) {
1340
1521
  return new ArcCommand(name);
@@ -1397,6 +1578,18 @@ class ArcContext {
1397
1578
  if (name === "$auth") {
1398
1579
  return authContext;
1399
1580
  }
1581
+ if (name === "get") {
1582
+ return (e) => {
1583
+ const element3 = this.elements.find((element4) => element4.name === e.name);
1584
+ if (!element3) {
1585
+ throw new Error(`Element "${String(name)}" not found`);
1586
+ }
1587
+ if (!element3.commandContext) {
1588
+ throw new Error(`Element "${String(name)}" does not have a command context`);
1589
+ }
1590
+ return element3.commandContext(dataStorage, publishEvent, authContext);
1591
+ };
1592
+ }
1400
1593
  const element2 = this.elements.find((element3) => element3.name === name);
1401
1594
  if (!element2) {
1402
1595
  throw new Error(`Element "${String(name)}" not found`);
@@ -1409,15 +1602,14 @@ class ArcContext {
1409
1602
  });
1410
1603
  }
1411
1604
  }
1412
- async function context(elementsPromise) {
1413
- const elements = await Promise.all(elementsPromise.map(async (element2) => {
1414
- if (element2 instanceof Promise) {
1415
- return (await element2).default;
1416
- }
1417
- return element2;
1418
- })).then((elements2) => elements2.filter(Boolean));
1605
+ function context(elements) {
1419
1606
  return new ArcContext(elements);
1420
1607
  }
1608
+ function contextMerge(...contexts) {
1609
+ return new ArcContext([
1610
+ ...contexts.map((context2) => context2.elements).flat()
1611
+ ]);
1612
+ }
1421
1613
  // context/event.ts
1422
1614
  var eventValidator = typeValidatorBuilder("object");
1423
1615
  var eventStoreSchema = {
@@ -1496,7 +1688,7 @@ class ArcEvent extends ArcContextElementWithStore {
1496
1688
  id: eventId.generate(),
1497
1689
  type: this.name,
1498
1690
  payload,
1499
- createdAt: new Date().toISOString()
1691
+ createdAt: new Date
1500
1692
  };
1501
1693
  await dataStorage.getStore("events").set(event);
1502
1694
  await publishEvent(event);
@@ -2342,6 +2534,18 @@ class ArcListener extends ArcContextElement {
2342
2534
  if (name === "$auth") {
2343
2535
  return authContext;
2344
2536
  }
2537
+ if (name === "get") {
2538
+ return (e) => {
2539
+ const element4 = this._elements.find((element5) => element5.name === e.name);
2540
+ if (!element4) {
2541
+ throw new Error(`Element "${String(name)}" not found in listener "${this.name}"`);
2542
+ }
2543
+ if (!element4.commandContext) {
2544
+ throw new Error(`Element "${String(name)}" does not have a command context`);
2545
+ }
2546
+ return element4.commandContext(dataStorage, publishEvent, authContext);
2547
+ };
2548
+ }
2345
2549
  const element3 = this._elements.find((element4) => element4.name === name);
2346
2550
  if (!element3) {
2347
2551
  throw new Error(`Element "${String(name)}" not found in listener "${this.name}"`);
@@ -2495,6 +2699,40 @@ class Model extends ModelBase {
2495
2699
  }
2496
2700
  });
2497
2701
  }
2702
+ routes(authContext) {
2703
+ return new Proxy({}, {
2704
+ get: (_, name) => {
2705
+ const element3 = this.context.elements.find((element4) => element4.name === name);
2706
+ if (!element3) {
2707
+ throw new Error(`Route element "${String(name)}" not found`);
2708
+ }
2709
+ if (typeof element3.getHandler !== "function") {
2710
+ throw new Error(`Element "${String(name)}" does not have route handlers`);
2711
+ }
2712
+ return async (method, req, routeParams, url) => {
2713
+ const handler = element3.getHandler(method);
2714
+ if (!handler) {
2715
+ throw new Error(`Method ${method} not allowed for route ${String(name)}`);
2716
+ }
2717
+ const forkedDataStorage = this.dataStorage.fork();
2718
+ const eventPublisher = new EventPublisher(this.context, this.dataStorage, authContext);
2719
+ const publishEvent = async (event3) => {
2720
+ await eventPublisher.publishEvent(event3, forkedDataStorage);
2721
+ };
2722
+ const commandContext = this.context.commandContext(forkedDataStorage, publishEvent, authContext);
2723
+ try {
2724
+ const result = await handler(commandContext, req, routeParams, url);
2725
+ await forkedDataStorage.merge();
2726
+ eventPublisher.runAsyncListeners();
2727
+ return result;
2728
+ } catch (error) {
2729
+ this.catchErrorCallback(error);
2730
+ throw error;
2731
+ }
2732
+ };
2733
+ }
2734
+ });
2735
+ }
2498
2736
  get $debug() {
2499
2737
  return {};
2500
2738
  }
@@ -2643,14 +2881,16 @@ class RemoteModelClient extends ModelBase {
2643
2881
  if (!response.ok) {
2644
2882
  throw new Error(`Query failed: ${response.statusText}`);
2645
2883
  }
2646
- const { result } = await response.json();
2647
- return result;
2884
+ return await response.json();
2648
2885
  }
2649
2886
  subscribe(queryBuilderFn, callback, authContext) {
2650
2887
  const result = this.query(queryBuilderFn, authContext);
2651
2888
  result.then((initialResult) => {
2652
2889
  callback(initialResult);
2653
- }).catch(this.catchErrorCallback);
2890
+ }).catch((error) => {
2891
+ console.error("Error in subscribe", error);
2892
+ callback(null);
2893
+ });
2654
2894
  return {
2655
2895
  unsubscribe: () => {},
2656
2896
  result
@@ -2688,6 +2928,95 @@ class RemoteModelClient extends ModelBase {
2688
2928
  });
2689
2929
  return commandsProxy;
2690
2930
  }
2931
+ routes(authContext) {
2932
+ throw new Error("Remote model client does not support route execution");
2933
+ }
2934
+ }
2935
+ // route/route.ts
2936
+ class ArcRoute extends ArcContextElement {
2937
+ name;
2938
+ _description;
2939
+ _path;
2940
+ _elements;
2941
+ _handlers;
2942
+ _isPublic = false;
2943
+ constructor(name) {
2944
+ super();
2945
+ this.name = name;
2946
+ }
2947
+ use(elements) {
2948
+ const clone = this.clone();
2949
+ clone._elements = elements;
2950
+ return clone;
2951
+ }
2952
+ description(description) {
2953
+ const clone = this.clone();
2954
+ clone._description = description;
2955
+ return clone;
2956
+ }
2957
+ path(path) {
2958
+ const clone = this.clone();
2959
+ clone._path = path;
2960
+ return clone;
2961
+ }
2962
+ public() {
2963
+ const clone = this.clone();
2964
+ clone._isPublic = true;
2965
+ return clone;
2966
+ }
2967
+ get isPublic() {
2968
+ return this._isPublic;
2969
+ }
2970
+ get routePath() {
2971
+ return this._path || `/${this.name}`;
2972
+ }
2973
+ handle(handlers) {
2974
+ const clone = this.clone();
2975
+ clone._handlers = handlers;
2976
+ return clone;
2977
+ }
2978
+ getHandler(method) {
2979
+ return this._handlers?.[method];
2980
+ }
2981
+ matchesPath(pathname) {
2982
+ const routePath = this.routePath;
2983
+ const routeParts = routePath.split("/").filter(Boolean);
2984
+ const pathParts = pathname.split("/").filter(Boolean);
2985
+ if (routeParts.length !== pathParts.length) {
2986
+ return { matches: false, params: {} };
2987
+ }
2988
+ const params = {};
2989
+ for (let i = 0;i < routeParts.length; i++) {
2990
+ const routePart = routeParts[i];
2991
+ const pathPart = pathParts[i];
2992
+ if (routePart.startsWith(":")) {
2993
+ const paramName = routePart.slice(1);
2994
+ params[paramName] = pathPart;
2995
+ } else if (routePart !== pathPart) {
2996
+ return { matches: false, params: {} };
2997
+ }
2998
+ }
2999
+ return { matches: true, params };
3000
+ }
3001
+ matchesRoutePath(pathname) {
3002
+ const { matches, params } = this.matchesPath(pathname);
3003
+ if (matches) {
3004
+ return { matches: true, isPublic: this._isPublic, params };
3005
+ }
3006
+ return { matches: false, isPublic: false };
3007
+ }
3008
+ clone() {
3009
+ const clone = new ArcRoute(this.name);
3010
+ clone._description = this._description;
3011
+ clone._path = this._path;
3012
+ clone._handlers = this._handlers;
3013
+ clone._elements = this._elements;
3014
+ clone._isPublic = this._isPublic;
3015
+ return clone;
3016
+ }
3017
+ }
3018
+ function route(name) {
3019
+ return new ArcRoute(name);
2691
3020
  }
2692
3021
  // rtc/client.ts
2693
3022
  class RTCClient {
@@ -2795,22 +3124,6 @@ class ArcViewQuery extends ArcSerializableQuery {
2795
3124
  }
2796
3125
 
2797
3126
  // view/queries/find.ts
2798
- class QueryViewResult {
2799
- result;
2800
- constructor(result) {
2801
- this.result = result;
2802
- }
2803
- get(id3) {
2804
- return id3 ? this.result.find((r) => r._id === id3) : undefined;
2805
- }
2806
- map(callbackfn) {
2807
- return this.result.map(callbackfn);
2808
- }
2809
- toArray() {
2810
- return this.result;
2811
- }
2812
- }
2813
-
2814
3127
  class ArcViewFindQuery extends ArcViewQuery {
2815
3128
  params;
2816
3129
  constructor(view, params) {
@@ -2857,7 +3170,7 @@ class ArcViewFindQuery extends ArcViewQuery {
2857
3170
  }
2858
3171
  onChange(change) {
2859
3172
  const lastResult = this.lastResult;
2860
- const lastResultAsArray = lastResult?.toArray() || [];
3173
+ const lastResultAsArray = lastResult || [];
2861
3174
  const index = lastResultAsArray.findIndex((e) => e._id === (change.type === "delete" ? change.id : change.id));
2862
3175
  const isInLastResult = index !== -1;
2863
3176
  const shouldBeInTheResult = change.type !== "delete" && this.checkItem(change.item);
@@ -2870,7 +3183,7 @@ class ArcViewFindQuery extends ArcViewQuery {
2870
3183
  return false;
2871
3184
  }
2872
3185
  createResult(result) {
2873
- return new QueryViewResult(result);
3186
+ return result;
2874
3187
  }
2875
3188
  }
2876
3189
 
@@ -2896,19 +3209,6 @@ class ArcViewFindQueryBuilder {
2896
3209
  }
2897
3210
 
2898
3211
  // view/queries/find-one.ts
2899
- class QueryViewFindOneResult {
2900
- result;
2901
- constructor(result) {
2902
- this.result = result;
2903
- }
2904
- get() {
2905
- return this.result;
2906
- }
2907
- exists() {
2908
- return this.result !== undefined;
2909
- }
2910
- }
2911
-
2912
3212
  class ArcViewFindOneQuery extends ArcViewQuery {
2913
3213
  params;
2914
3214
  constructor(view, params) {
@@ -2955,7 +3255,7 @@ class ArcViewFindOneQuery extends ArcViewQuery {
2955
3255
  }
2956
3256
  onChange(change) {
2957
3257
  const lastResult = this.lastResult;
2958
- const currentItem = lastResult?.get();
3258
+ const currentItem = lastResult;
2959
3259
  const itemId = change.type === "delete" ? change.id : change.id;
2960
3260
  const hasCurrentItem = currentItem !== undefined;
2961
3261
  const isCurrentItem = hasCurrentItem && currentItem._id === itemId;
@@ -2969,7 +3269,7 @@ class ArcViewFindOneQuery extends ArcViewQuery {
2969
3269
  return false;
2970
3270
  }
2971
3271
  createResult(result) {
2972
- return new QueryViewFindOneResult(result);
3272
+ return result;
2973
3273
  }
2974
3274
  }
2975
3275
 
@@ -3038,6 +3338,14 @@ class ArcView extends ArcContextElementWithStore {
3038
3338
  clone._handler = handler;
3039
3339
  return clone;
3040
3340
  }
3341
+ handleEvent(event3, handler) {
3342
+ const clone = this.clone();
3343
+ clone._handler = {
3344
+ ...clone._handler ?? {},
3345
+ [event3.name]: handler
3346
+ };
3347
+ return clone;
3348
+ }
3041
3349
  applyRestrictions(authContext, options) {
3042
3350
  if (!this.restrictions) {
3043
3351
  return options;
@@ -3157,8 +3465,10 @@ export {
3157
3465
  stringEnum,
3158
3466
  string,
3159
3467
  rtcClientFactory,
3468
+ route,
3160
3469
  record,
3161
3470
  reactive,
3471
+ or,
3162
3472
  object,
3163
3473
  number,
3164
3474
  listener,
@@ -3169,12 +3479,15 @@ export {
3169
3479
  date,
3170
3480
  customId,
3171
3481
  createSQLiteAdapterFactory,
3482
+ contextMerge,
3172
3483
  context,
3173
3484
  command,
3174
3485
  collection,
3175
3486
  boolean,
3176
3487
  blob,
3177
3488
  array,
3489
+ arcObjectToStoreSchema,
3490
+ any,
3178
3491
  StoreState,
3179
3492
  SQLiteAdapter,
3180
3493
  RemoteModelClient,
@@ -3190,9 +3503,11 @@ export {
3190
3503
  ArcView,
3191
3504
  ArcStringEnum,
3192
3505
  ArcString,
3506
+ ArcRoute,
3193
3507
  ArcRecord,
3194
3508
  ArcQueryBuilder,
3195
3509
  ArcQuery,
3510
+ ArcOr,
3196
3511
  ArcOptional,
3197
3512
  ArcObject,
3198
3513
  ArcNumber,
@@ -3211,5 +3526,6 @@ export {
3211
3526
  ArcBranded,
3212
3527
  ArcBoolean,
3213
3528
  ArcBlob,
3214
- ArcArray
3529
+ ArcArray,
3530
+ ArcAny
3215
3531
  };
@@ -15,6 +15,7 @@ export declare abstract class ModelBase<C extends ArcContextAny> {
15
15
  unsubscribe: () => void;
16
16
  };
17
17
  abstract commands(authContext: AuthContext): ArcContextElementMethodReturnType<C["elements"], "commandClient">;
18
+ abstract routes(authContext: AuthContext): any;
18
19
  }
19
20
  export declare class Model<C extends ArcContextAny> extends ModelBase<C> {
20
21
  private readonly context;
@@ -28,6 +29,7 @@ export declare class Model<C extends ArcContextAny> extends ModelBase<C> {
28
29
  unsubscribe: () => void;
29
30
  };
30
31
  commands(authContext: AuthContext): ArcContextElementMethodReturnType<C["elements"], "commandClient">;
32
+ routes(authContext: AuthContext): any;
31
33
  get $debug(): {};
32
34
  }
33
35
  export declare class RemoteModelClient<C extends ArcContextAny> extends ModelBase<C> {
@@ -62,6 +64,7 @@ export declare class RemoteModelClient<C extends ArcContextAny> extends ModelBas
62
64
  unsubscribe: () => void;
63
65
  };
64
66
  commands(authContext: AuthContext): ArcContextElementMethodReturnType<C["elements"], "commandClient">;
67
+ routes(authContext: AuthContext): any;
65
68
  }
66
69
  export {};
67
70
  //# sourceMappingURL=model.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from "./route";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,35 @@
1
+ import type { ArcCommandContext } from "../context";
2
+ import { ArcContextElement, type ArcContextElementAny } from "../context/element";
3
+ export type ArcRouteHandler<ContextElements extends ArcContextElementAny[]> = (ctx: ArcCommandContext<ContextElements>, request: Request, params: Record<string, string>, url: URL) => Promise<Response> | Response;
4
+ export type ArcRouteHandlers<ContextElements extends ArcContextElementAny[]> = {
5
+ [Method in "GET" | "POST" | "PUT" | "DELETE" | "PATCH"]?: ArcRouteHandler<ContextElements>;
6
+ };
7
+ export declare class ArcRoute<Name extends string, const Elements extends ArcContextElementAny[]> extends ArcContextElement<null, Name> {
8
+ readonly name: Name;
9
+ private _description?;
10
+ private _path?;
11
+ private _elements?;
12
+ private _handlers?;
13
+ private _isPublic;
14
+ constructor(name: Name);
15
+ use<const E extends ArcContextElementAny[]>(elements: E): ArcRoute<Name, E>;
16
+ description(description: string): ArcRoute<Name, Elements>;
17
+ path(path: string): ArcRoute<Name, Elements>;
18
+ public(): ArcRoute<Name, Elements>;
19
+ get isPublic(): boolean;
20
+ get routePath(): string;
21
+ handle(handlers: ArcRouteHandlers<Elements>): ArcRoute<Name, Elements>;
22
+ getHandler(method: string): ArcRouteHandler<Elements> | undefined;
23
+ matchesPath(pathname: string): {
24
+ matches: boolean;
25
+ params: Record<string, string>;
26
+ };
27
+ matchesRoutePath(pathname: string): {
28
+ matches: boolean;
29
+ isPublic: boolean;
30
+ params?: Record<string, string>;
31
+ };
32
+ private clone;
33
+ }
34
+ export declare function route<Name extends string>(name: Name): ArcRoute<Name, any[]>;
35
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1,2 @@
1
+ export * from "./arcObjectToStoreSchema";
2
+ //# sourceMappingURL=index.d.ts.map
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { ArcCollectionAny, CollectionItem } from "./collection/collection";
2
2
  import type { QueryCollectionResult } from "./collection/queries/find";
3
3
  import type { ArcElement } from "./elements/element";
4
+ export * from "./utils/index";
4
5
  export declare namespace objectUtil {
5
6
  export type MergeShapes<U, V> = {
6
7
  [k in Exclude<keyof U, keyof V>]: U[k];
@@ -1,18 +1,12 @@
1
1
  import type { ListenerEvent, StoreState } from "../../data-storage";
2
2
  import type { FindOptions } from "../../data-storage/types";
3
3
  import { ArcViewQuery, type ArcViewAny, type ArcViewItem } from "./abstract-view-query";
4
- export declare class QueryViewFindOneResult<V extends ArcViewAny> {
5
- private result;
6
- constructor(result: ArcViewItem<V["id"], V["schema"]> | undefined);
7
- get(): ArcViewItem<V["id"], V["schema"]> | undefined;
8
- exists(): boolean;
9
- }
10
- export declare class ArcViewFindOneQuery<View extends ArcViewAny> extends ArcViewQuery<View, QueryViewFindOneResult<View>, FindOptions<ArcViewItem<View["id"], View["schema"]>>> {
4
+ export declare class ArcViewFindOneQuery<View extends ArcViewAny> extends ArcViewQuery<View, ArcViewItem<View["id"], View["schema"]> | undefined, FindOptions<ArcViewItem<View["id"], View["schema"]>>> {
11
5
  protected params: FindOptions<ArcViewItem<View["id"], View["schema"]>>;
12
6
  constructor(view: View, params: FindOptions<ArcViewItem<View["id"], View["schema"]>>);
13
- protected fetch(store: StoreState<ArcViewItem<View["id"], View["schema"]>>): Promise<QueryViewFindOneResult<View>>;
7
+ protected fetch(store: StoreState<ArcViewItem<View["id"], View["schema"]>>): Promise<ArcViewItem<View["id"], View["schema"]> | undefined>;
14
8
  protected checkItem(item: ArcViewItem<View["id"], View["schema"]>): boolean;
15
- protected onChange(change: ListenerEvent<ArcViewItem<View["id"], View["schema"]>>): false | QueryViewFindOneResult<View>;
16
- protected createResult(result: ArcViewItem<View["id"], View["schema"]> | undefined): QueryViewFindOneResult<View>;
9
+ protected onChange(change: ListenerEvent<ArcViewItem<View["id"], View["schema"]>>): false | ArcViewItem<View["id"], View["schema"]> | undefined;
10
+ protected createResult(result: ArcViewItem<View["id"], View["schema"]> | undefined): ArcViewItem<View["id"], View["schema"]> | undefined;
17
11
  }
18
12
  //# sourceMappingURL=find-one.d.ts.map
@@ -9,12 +9,12 @@ export declare class QueryViewResult<V extends ArcViewAny> {
9
9
  map<U>(callbackfn: (value: ArcViewItem<V["id"], V["schema"]>, index: number, array: ArcViewItem<V["id"], V["schema"]>[]) => U): U[];
10
10
  toArray(): ArcViewItem<V["id"], V["schema"]>[];
11
11
  }
12
- export declare class ArcViewFindQuery<View extends ArcViewAny> extends ArcViewQuery<View, QueryViewResult<View>, FindOptions<ArcViewItem<View["id"], View["schema"]>>> {
12
+ export declare class ArcViewFindQuery<View extends ArcViewAny> extends ArcViewQuery<View, ArcViewItem<View["id"], View["schema"]>[], FindOptions<ArcViewItem<View["id"], View["schema"]>>> {
13
13
  protected params: FindOptions<ArcViewItem<View["id"], View["schema"]>>;
14
14
  constructor(view: View, params: FindOptions<ArcViewItem<View["id"], View["schema"]>>);
15
- protected fetch(store: StoreState<ArcViewItem<View["id"], View["schema"]>>): Promise<QueryViewResult<View>>;
15
+ protected fetch(store: StoreState<ArcViewItem<View["id"], View["schema"]>>): Promise<ArcViewItem<View["id"], View["schema"]>[]>;
16
16
  protected checkItem(item: ArcViewItem<View["id"], View["schema"]>): boolean;
17
- protected onChange(change: ListenerEvent<ArcViewItem<View["id"], View["schema"]>>): false | QueryViewResult<View>;
18
- protected createResult(result: ArcViewItem<View["id"], View["schema"]>[]): QueryViewResult<View>;
17
+ protected onChange(change: ListenerEvent<ArcViewItem<View["id"], View["schema"]>>): false | ArcViewItem<View["id"], View["schema"]>[];
18
+ protected createResult(result: ArcViewItem<View["id"], View["schema"]>[]): ArcViewItem<View["id"], View["schema"]>[];
19
19
  }
20
20
  //# sourceMappingURL=find.d.ts.map
@@ -7,7 +7,7 @@ export declare class ArcViewFindOneQueryBuilder<V extends ArcViewAny> {
7
7
  protected queryContext: QueryBuilderContext;
8
8
  protected options: FindOptions<ArcViewItem<V["id"], V["schema"]>>;
9
9
  constructor(view: V, queryContext: QueryBuilderContext, options: FindOptions<ArcViewItem<V["id"], V["schema"]>>);
10
- toQuery(): ArcViewFindOneQuery<ArcViewAny>;
11
- run(): import("../queries/find-one").QueryViewFindOneResult<ArcViewAny>;
10
+ toQuery(): ArcViewFindOneQuery<V>;
11
+ run(): ArcViewItem<V["id"], V["schema"]> | undefined;
12
12
  }
13
13
  //# sourceMappingURL=find-one.d.ts.map
@@ -7,7 +7,7 @@ export declare class ArcViewFindQueryBuilder<V extends ArcViewAny> {
7
7
  protected queryContext: QueryBuilderContext;
8
8
  protected options: FindOptions<ArcViewItem<V["id"], V["schema"]>>;
9
9
  constructor(view: V, queryContext: QueryBuilderContext, options: FindOptions<ArcViewItem<V["id"], V["schema"]>>);
10
- toQuery(): ArcViewFindQuery<ArcViewAny>;
11
- run(): import("..").QueryViewResult<ArcViewAny>;
10
+ toQuery(): ArcViewFindQuery<V>;
11
+ run(): ArcViewItem<V["id"], V["schema"]>[];
12
12
  }
13
13
  //# sourceMappingURL=find.d.ts.map
@@ -1,9 +1,10 @@
1
+ import type { ArcEventAny, ArcEventInstance } from "../context";
1
2
  import { ArcContextElementWithStore, type ArcContextElementAny, type AuthContext, type ListenerConfig, type PublishEventFunction, type StoreSchema } from "../context/element";
2
3
  import type { QueryBuilderContext } from "../context/query-builder-context";
3
4
  import type { DataStorage } from "../data-storage";
4
5
  import type { FindOptions, WhereCondition } from "../data-storage/types";
5
6
  import { type ArcIdAny, type ArcObjectAny } from "../elements";
6
- import type { $type } from "../utils";
7
+ import type { $type, objectUtil } from "../utils";
7
8
  import { ArcViewFindQueryBuilder } from "./query-builders/find";
8
9
  import { ArcViewFindOneQueryBuilder } from "./query-builders/find-one";
9
10
  type GetEvents<Elements extends ArcContextElementAny[]> = Elements[number]["$event"];
@@ -19,8 +20,9 @@ type ArcViewItem<Id extends ArcIdAny, Schema extends ArcObjectAny> = {
19
20
  _id: $type<Id>;
20
21
  } & $type<Schema>;
21
22
  type ArcViewHandler<Elements extends ArcContextElementAny[], Id extends ArcIdAny, Schema extends ArcObjectAny> = {
22
- [Event in GetEvents<Elements> as Event["type"]]: (ctx: ArcViewHandlerContext<Id, Schema>, event: Event) => Promise<void>;
23
+ [Event in GetEvents<Elements> as Event["type"]]: ArcViewEventHandler<Id, Schema, Event>;
23
24
  };
25
+ type ArcViewEventHandler<Id extends ArcIdAny, Schema extends ArcObjectAny, Event extends any> = (ctx: ArcViewHandlerContext<Id, Schema>, event: Event) => Promise<void>;
24
26
  export declare class ArcView<Name extends string, Id extends ArcIdAny, Schema extends ArcObjectAny, const Elements extends ArcContextElementAny[]> extends ArcContextElementWithStore<null, Name> {
25
27
  readonly name: Name;
26
28
  readonly id: Id;
@@ -41,6 +43,7 @@ export declare class ArcView<Name extends string, Id extends ArcIdAny, Schema ex
41
43
  description(description: string): ArcView<Name, Id, Schema, Elements>;
42
44
  async(): ArcView<Name, Id, Schema, Elements>;
43
45
  handle<Handler extends ArcViewHandler<Elements, Id, Schema>>(handler: Handler): ArcView<Name, Id, Schema, Elements>;
46
+ handleEvent<Event extends ArcEventAny>(event: Event, handler: ArcViewEventHandler<Id, Schema, ArcEventInstance<Event>>): ArcView<Name, Id, Schema, [...Elements, Event]>;
44
47
  /**
45
48
  * Helper function to merge where conditions from restrictions with query options
46
49
  */
@@ -57,5 +60,6 @@ export declare class ArcView<Name extends string, Id extends ArcIdAny, Schema ex
57
60
  private clone;
58
61
  }
59
62
  export declare function view<Name extends string, Id extends ArcIdAny, Schema extends ArcObjectAny>(name: Name, id: Id, schema: Schema): ArcView<Name, Id, Schema, any[]>;
63
+ export type ArcViewRecord<View extends ArcView<any, any, any, any>> = objectUtil.simplify<ArcViewItem<View["id"], View["schema"]>>;
60
64
  export {};
61
65
  //# sourceMappingURL=view.d.ts.map
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",
4
+ "version": "0.1.6",
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.",