@arcote.tech/arc 0.4.10 → 0.5.1

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.
@@ -6,22 +6,17 @@
6
6
  */
7
7
  import type { ArcIdAny } from "../../elements/id";
8
8
  import type { ArcObjectAny } from "../../elements/object";
9
- import type { ArcEventAny } from "../event/event";
10
9
  import type { Simplify } from "../../utils";
10
+ import type { ArcEventAny } from "../event/event";
11
11
  import type { ArcEventInstance } from "../event/instance";
12
12
  import type { ArcViewHandlerContext } from "../view/view-context";
13
13
  import type { ViewProtection } from "../view/view-data";
14
14
  /**
15
15
  * Handler for an aggregate event — same signature as ArcView handler.
16
- * Receives ctx with set/modify/remove and the event instance.
17
16
  */
18
17
  export type AggregateEventHandler<Id extends ArcIdAny, Schema extends ArcObjectAny, Event extends ArcEventAny> = (ctx: ArcViewHandlerContext<Id, Schema>, event: ArcEventInstance<Event>) => Promise<void>;
19
18
  /**
20
19
  * Entry in the aggregate's event registry.
21
- * Pairs an ArcEvent instance with its view handler.
22
- *
23
- * - isInline: true if event was created via .event() or .publicEvent() (inline definition)
24
- * - isPublic: true if event was created via .publicEvent() (accessible via getEvent())
25
20
  */
26
21
  export interface AggregateEventEntry<Event extends ArcEventAny = ArcEventAny, Id extends ArcIdAny = ArcIdAny, Schema extends ArcObjectAny = ArcObjectAny, IsPublic extends boolean = boolean> {
27
22
  readonly event: Event;
@@ -29,34 +24,19 @@ export interface AggregateEventEntry<Event extends ArcEventAny = ArcEventAny, Id
29
24
  readonly isInline: boolean;
30
25
  readonly isPublic: IsPublic;
31
26
  }
32
- /**
33
- * Context passed to mutateMethod handlers.
34
- * Provides emit per registered event + $auth from adapters.
35
- */
36
- export type AggregateMutateContext<Events extends AggregateEventEntry[]> = {
37
- [E in Events[number] as E["event"]["name"]]: {
38
- emit: (payload: any) => Promise<void>;
39
- };
40
- } & {
41
- $auth: {
42
- params: any;
43
- tokenName: string;
44
- };
45
- };
46
27
  /**
47
28
  * Entry in the aggregate's mutateMethod registry.
48
- * Defines a named mutation exposed via mutateContext/useCommands.
29
+ * Stores the ArcFunction for runtime infrastructure + fields for type extraction.
49
30
  */
50
31
  export interface AggregateMutateMethodEntry {
51
32
  readonly name: string;
52
- readonly params: ArcObjectAny;
53
- readonly handler: ((ctx: any, params: any) => Promise<any>) | false;
33
+ readonly params: ArcObjectAny | null;
34
+ readonly handler: Function | false | null;
54
35
  readonly result?: any;
55
36
  readonly cronExpression?: string;
56
37
  }
57
38
  /**
58
39
  * Cron method entry extracted at build time.
59
- * Used by CronScheduler to discover and register cron jobs.
60
40
  */
61
41
  export interface AggregateCronMethodEntry {
62
42
  readonly aggregateName: string;
@@ -65,17 +45,15 @@ export interface AggregateCronMethodEntry {
65
45
  }
66
46
  /**
67
47
  * Entry in the aggregate's clientQuery registry.
68
- * Defines a named query exposed via queryContext/useQuery.
69
48
  */
70
49
  export interface AggregateQueryMethodEntry {
71
50
  readonly name: string;
72
- readonly handler: (...args: any[]) => Promise<any>;
51
+ readonly handler: Function | false | null;
73
52
  }
74
53
  /**
75
- * Maps MutateMethods tuple { methodName: (params) => Promise<ReturnType> }
76
- * Used as return type of mutateContext() on ArcAggregateElement.
54
+ * Resolve mutateMethod return type from entry fields.
55
+ * explicit result > handler return > Promise<any>
77
56
  */
78
- /** Resolve mutateMethod return type: explicit result > handler return > Promise<any> */
79
57
  type MutateReturn<M> = M extends {
80
58
  result: infer R;
81
59
  } ? [R] extends [never] ? M extends {
@@ -83,6 +61,10 @@ type MutateReturn<M> = M extends {
83
61
  } ? Promise<HR> : Promise<any> : Promise<R> : M extends {
84
62
  handlerReturn: infer HR;
85
63
  } ? Promise<HR> : Promise<any>;
64
+ /**
65
+ * Maps MutateMethods tuple → { methodName: (params) => Promise<ReturnType> }
66
+ * Used as return type of mutateContext().
67
+ */
86
68
  export type AggregateMutateMethodContext<MutateMethods extends AggregateMutateMethodEntry[]> = {
87
69
  [M in MutateMethods[number] as M["name"]]: M["params"] extends {
88
70
  deserialize: (...a: any) => infer P;
@@ -90,15 +72,13 @@ export type AggregateMutateMethodContext<MutateMethods extends AggregateMutateMe
90
72
  };
91
73
  /**
92
74
  * Maps QueryMethods tuple → { methodName: consumer API }
93
- * Extracts params and return type directly from handler.
94
- * Uses rest args pattern so handlers without params produce no-arg consumer methods.
75
+ * Extracts args and return type directly from handler (same as pre-refactor).
95
76
  */
96
77
  export type AggregateQueryContext<QueryMethods extends AggregateQueryMethodEntry[]> = {
97
78
  [M in QueryMethods[number] as M["name"]]: M["handler"] extends (ctx: any, ...args: infer Args) => Promise<infer R> ? (...args: Args) => Promise<Simplify<R>> : never;
98
79
  };
99
80
  /**
100
81
  * Static configuration stored on the aggregate constructor.
101
- * Read by aggregateContextElement() to build the ArcContextElement.
102
82
  */
103
83
  export interface AggregateStaticConfig {
104
84
  readonly __aggregateName: string;
@@ -1,14 +1,12 @@
1
1
  /**
2
2
  * ArcAggregateElement — unified aggregate builder + context element.
3
3
  *
4
- * aggregate() returns this directly. No .build() or aggregateContextElement() needed.
4
+ * aggregate() returns this directly. No .build() needed.
5
5
  * Each builder method returns a new immutable instance.
6
6
  *
7
- * From the framework's perspective, behaves like a view:
8
- * - queryContext() → named query methods
9
- * - mutateContext() named mutation methods
10
- * - getHandlers() / getElements() → for eventPublisher registration
11
- * - databaseStoreSchema() → table schema
7
+ * mutateMethod/clientQuery use the ArcFunction callback pattern:
8
+ * .mutateMethod('create', fn => fn.withParams({...}).handle(...))
9
+ * .clientQuery('getAll', fn => fn.handle(async ctx => ctx.$query.find({})))
12
10
  */
13
11
  import type { DatabaseStoreSchema } from "../../data-storage/database-store";
14
12
  import type { ArcIdAny } from "../../elements/id";
@@ -20,6 +18,8 @@ import type { ArcTokenAny } from "../../token/token";
20
18
  import { ArcContextElement } from "../context-element";
21
19
  import { ArcEvent, type ArcEventAny } from "../event/event";
22
20
  import type { ArcEventInstance } from "../event/instance";
21
+ import { ArcFunction, type DefaultFunctionData } from "../function/arc-function";
22
+ import type { ArcFunctionData } from "../function/arc-function-data";
23
23
  import type { ArcViewHandlerContext, ArcViewItem } from "../view/view-context";
24
24
  import type { ViewProtection, ViewProtectionFn } from "../view/view-data";
25
25
  import { AggregateBase } from "./aggregate-base";
@@ -42,7 +42,11 @@ type AggregatePrivateQuery<Id extends ArcIdAny, Schema extends ArcObjectAny> = {
42
42
  (where?: any): Promise<AggregateRow<Id, Schema> | undefined>;
43
43
  };
44
44
  };
45
- type MutateMethodContext<Id extends ArcIdAny, Schema extends ArcObjectAny, Events extends AggregateEventEntry[]> = {
45
+ /**
46
+ * ExtraCtx for mutateMethod handlers.
47
+ * Event emitters + $query + $auth — injected by aggregate.
48
+ */
49
+ type MutateMethodExtraCtx<Id extends ArcIdAny, Schema extends ArcObjectAny, Events extends AggregateEventEntry[]> = {
46
50
  [E in Events[number] as E["event"]["name"]]: {
47
51
  emit: (payload: E["event"]["payload"] extends {
48
52
  deserialize: (...a: any) => any;
@@ -55,7 +59,10 @@ type MutateMethodContext<Id extends ArcIdAny, Schema extends ArcObjectAny, Event
55
59
  };
56
60
  $query: AggregatePrivateQuery<Id, Schema>;
57
61
  };
58
- type ClientQueryContext<Id extends ArcIdAny, Schema extends ArcObjectAny, Events extends AggregateEventEntry[]> = {
62
+ /**
63
+ * ExtraCtx for clientQuery handlers.
64
+ */
65
+ type ClientQueryExtraCtx<Id extends ArcIdAny, Schema extends ArcObjectAny, Events extends AggregateEventEntry[]> = {
59
66
  $query: AggregatePrivateQuery<Id, Schema>;
60
67
  $auth: {
61
68
  params: any;
@@ -91,10 +98,8 @@ export type AggregateConstructor<Id extends ArcIdAny = ArcIdAny, Schema extends
91
98
  getEvent<EventName extends PublicEventNames<Events>>(name: EventName): GetPublicEvent<Events, EventName>;
92
99
  };
93
100
  export type AggregateConstructorAny = AggregateConstructor<any, any, any>;
94
- /** Extract the full row type from an aggregate element. */
95
101
  export type AggregateData<El extends ArcAggregateElement<any, any, any, any, any>> = AggregateRow<El extends ArcAggregateElement<infer _N, infer I, any, any, any> ? I : never, El extends ArcAggregateElement<infer _N, any, infer S, any, any> ? S : never>;
96
102
  export declare class ArcAggregateElement<Name extends string = string, Id extends ArcIdAny = ArcIdAny, Schema extends ArcObjectAny = ArcObjectAny, Events extends AggregateEventEntry[] = AggregateEventEntry[], MutateMethods extends AggregateMutateMethodEntry[] = AggregateMutateMethodEntry[], QueryMethods extends AggregateQueryMethodEntry[] = AggregateQueryMethodEntry[]> extends ArcContextElement<Name> {
97
- /** Expose schema for eventPublisher view registration (duck typing) */
98
103
  readonly schema: Schema;
99
104
  private readonly _id_factory;
100
105
  private readonly _events;
@@ -119,53 +124,75 @@ export declare class ArcAggregateElement<Name extends string = string, Id extend
119
124
  ...Events,
120
125
  AggregateEventEntry<E, ArcIdAny, ArcObjectAny, false>
121
126
  ], MutateMethods, QueryMethods>;
122
- mutateMethod<const MethodName extends string, ParamsShape extends ArcRawShape, HR = void, R = never>(methodName: MethodName, config: {
123
- params: ParamsShape;
124
- result?: R;
125
- }, handler: ((ctx: MutateMethodContext<Id, Schema, Events>, params: $type<ArcObject<ParamsShape>>) => Promise<HR>) | false): ArcAggregateElement<Name, Id, Schema, Events, [
127
+ /**
128
+ * Define a mutation method using ArcFunction callback pattern.
129
+ *
130
+ * The callback receives an ArcFunction pre-configured with ExtraCtx
131
+ * containing event emitters, $query, and $auth.
132
+ *
133
+ * @example
134
+ * ```typescript
135
+ * .mutateMethod('create', fn => fn
136
+ * .withParams({ title: string() })
137
+ * .withResult({ id: string() })
138
+ * .handle(async (ctx, params) => {
139
+ * const id = taskId.generate();
140
+ * await ctx.created.emit({ title: params.title });
141
+ * return { id };
142
+ * })
143
+ * )
144
+ * ```
145
+ */
146
+ mutateMethod<const MethodName extends string, ReturnFn extends ArcFunction<ArcFunctionData, MutateMethodExtraCtx<Id, Schema, Events>>>(methodName: MethodName, configure: (fn: ArcFunction<DefaultFunctionData, MutateMethodExtraCtx<Id, Schema, Events>>) => ReturnFn): ArcAggregateElement<Name, Id, Schema, Events, [
126
147
  ...MutateMethods,
127
148
  {
128
149
  name: MethodName;
129
- params: ArcObject<ParamsShape>;
130
- handler: typeof handler;
131
- handlerReturn: HR;
132
- result: R;
150
+ params: ReturnFn["data"]["params"];
151
+ handler: ReturnFn["data"]["handler"];
152
+ handlerReturn: ReturnFn["data"]["handler"] extends (...args: any[]) => Promise<infer HR> ? HR : void;
153
+ result: ReturnFn["data"]["result"] extends ArcObjectAny ? $type<ReturnFn["data"]["result"]> : never;
133
154
  }
134
155
  ], QueryMethods>;
135
156
  cron(expression: string): ArcAggregateElement<Name, Id, Schema, Events, MutateMethods, QueryMethods>;
136
- clientQuery<const MethodName extends string, H extends (ctx: ClientQueryContext<Id, Schema, Events>, ...args: any[]) => Promise<any>>(methodName: MethodName, handler: H): ArcAggregateElement<Name, Id, Schema, Events, MutateMethods, [
157
+ /**
158
+ * Define a client query method using ArcFunction callback pattern.
159
+ *
160
+ * The callback receives an ArcFunction pre-configured with ExtraCtx
161
+ * containing $query, $auth, and Aggregate constructor.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * .clientQuery('getAll', fn => fn
166
+ * .handle(async (ctx) => ctx.$query.find({}))
167
+ * )
168
+ * .clientQuery('getById', fn => fn
169
+ * .withParams({ id: taskId })
170
+ * .handle(async (ctx, { id }) => ctx.$query.findOne({ _id: id }))
171
+ * )
172
+ * ```
173
+ */
174
+ clientQuery<const MethodName extends string, ReturnFn extends ArcFunction<ArcFunctionData, ClientQueryExtraCtx<Id, Schema, Events>>>(methodName: MethodName, configure: (fn: ArcFunction<DefaultFunctionData, ClientQueryExtraCtx<Id, Schema, Events>>) => ReturnFn): ArcAggregateElement<Name, Id, Schema, Events, MutateMethods, [
137
175
  ...QueryMethods,
138
176
  {
139
177
  name: MethodName;
140
- handler: H;
178
+ handler: ReturnFn["data"]["handler"];
141
179
  }
142
180
  ]>;
143
- /**
144
- * Declare seed data inserted after table creation.
145
- * Rows with `_id` use it as-is; rows without get auto-generated IDs.
146
- */
147
181
  seedWith(data: Array<$type<Schema> & {
148
182
  _id?: $type<Id>;
149
183
  }>, options?: {
150
184
  version?: number;
151
185
  }): ArcAggregateElement<Name, Id, Schema, Events, MutateMethods, QueryMethods>;
152
- /**
153
- * Return a copy with seed data attached.
154
- * Use with context.replace() to add seeds to framework-provided aggregates.
155
- */
156
186
  withSeeds(data: Array<$type<Schema> & {
157
187
  _id?: $type<Id>;
158
188
  }>, options?: {
159
189
  version?: number;
160
190
  }): ArcAggregateElement<Name, Id, Schema, Events, MutateMethods, QueryMethods>;
161
- /** The internal AggregateConstructor class. Use in clientQuery to extend with business methods. */
162
191
  get Aggregate(): AggregateConstructor<Id, Schema, Events>;
163
192
  private buildConstructor;
164
193
  getHandlers(): Record<string, (ctx: any, event: any) => Promise<void>>;
165
194
  getElements(): ArcEventAny[];
166
- /** Public event accessor (same as old static getEvent) */
167
195
  getEvent<EventName extends PublicEventNames<Events>>(eventName: EventName): GetPublicEvent<Events, EventName>;
168
- /** Cron methods for CronScheduler discovery */
169
196
  get cronMethods(): AggregateCronMethodEntry[];
170
197
  queryContext(adapters: ModelAdapters): AggregateQueryContext<QueryMethods>;
171
198
  private buildPrivateQuery;
@@ -1,34 +1,16 @@
1
- import type { ArcToken, ArcTokenAny } from "../../token/token";
2
- import type { $type } from "../../utils/types/get-type";
3
1
  import type { ArcContextElement } from "../context-element";
4
2
  import type { ElementContext } from "../element-context";
5
- import type { CommandProtection } from "./command-data";
6
- /**
7
- * Extract token params type from a token
8
- */
9
- type TokenParams<T extends ArcTokenAny> = T extends {
10
- paramsSchema: infer P extends {
11
- deserialize: (...args: any) => any;
12
- };
13
- } ? $type<P> : Record<string, any>;
14
- /**
15
- * Auth context type for protected commands
16
- * Provides access to token params from the authenticated user
17
- */
18
- export type AuthContext<T extends ArcTokenAny> = {
19
- params: TokenParams<T>;
20
- tokenName: T extends ArcToken<infer Name, any, any, any> ? Name : string;
21
- };
3
+ import type { FnAuthContext, FnProtection } from "../function/arc-function-data";
22
4
  /**
23
5
  * Extract union of all token types from protections array
24
6
  */
25
- type ProtectionTokens<Protections extends CommandProtection[]> = Protections[number]["token"];
7
+ type ProtectionTokens<Protections extends FnProtection[]> = Protections[number]["token"];
26
8
  /**
27
- * Command context provided to command handlers
28
- * Extends shared ElementContext with command-specific $auth support.
9
+ * Command context provided to command handlers.
10
+ * Extends shared ElementContext with $auth from protectedBy().
29
11
  */
30
- export type ArcCommandContext<QueryElements extends ArcContextElement<any>[], MutationElements extends ArcContextElement<any>[], Protections extends CommandProtection[] = []> = ElementContext<QueryElements, MutationElements> & (Protections extends [] ? object : {
31
- $auth: AuthContext<ProtectionTokens<Protections>>;
12
+ export type ArcCommandContext<QueryElements extends ArcContextElement<any>[], MutationElements extends ArcContextElement<any>[], Protections extends FnProtection[] = []> = ElementContext<QueryElements, MutationElements> & (Protections extends [] ? object : {
13
+ $auth: FnAuthContext<ProtectionTokens<Protections>>;
32
14
  });
33
15
  /**
34
16
  * Helper type to extract command context from command data
@@ -36,7 +18,7 @@ export type ArcCommandContext<QueryElements extends ArcContextElement<any>[], Mu
36
18
  export type ArcCommandContextFromData<Data> = Data extends {
37
19
  queryElements: infer Q extends ArcContextElement<any>[];
38
20
  mutationElements: infer M extends ArcContextElement<any>[];
39
- protections?: infer P extends CommandProtection[];
21
+ protections?: infer P extends FnProtection[];
40
22
  } ? ArcCommandContext<Q, M, P extends undefined ? [] : P> : never;
41
23
  export {};
42
24
  //# sourceMappingURL=command-context.d.ts.map
@@ -1,23 +1,14 @@
1
1
  import type { ArcObjectAny } from "../../elements/object";
2
- import type { ArcTokenAny } from "../../token/token";
3
- import type { TokenInstanceAny } from "../../token/token-instance";
4
2
  import type { ArcContextElement } from "../context-element";
3
+ import type { FnProtection, FnProtectionCheck } from "../function/arc-function-data";
5
4
  import type { ArcCommandHandler } from "./command-handler";
6
5
  /**
7
- * Protection check function for commands
8
- * Receives token instance and returns whether access is allowed
6
+ * Protection types aliases for unified FnProtection
9
7
  */
10
- export type CommandProtectionCheck<T extends ArcTokenAny> = (tokenInstance: TokenInstanceAny) => boolean | Promise<boolean>;
11
- /**
12
- * Protection configuration for a command
13
- */
14
- export type CommandProtection = {
15
- token: ArcTokenAny;
16
- check: CommandProtectionCheck<any>;
17
- };
8
+ export type CommandProtection = FnProtection;
9
+ export type CommandProtectionCheck<T> = FnProtectionCheck<any>;
18
10
  /**
19
11
  * Command data configuration
20
- * Contains all generic types and non-generic configuration in one object
21
12
  */
22
13
  export type ArcCommandData = {
23
14
  name: string;
@@ -6,160 +6,68 @@ import type { TokenInstanceAny } from "../../token/token-instance";
6
6
  import type { Merge } from "../../utils";
7
7
  import type { $type } from "../../utils/types/get-type";
8
8
  import { ArcContextElement } from "../context-element";
9
+ import { ArcFunction } from "../function/arc-function";
10
+ import type { FnProtection, FnProtectionCheck } from "../function/arc-function-data";
9
11
  import type { ArcCommandContextFromData } from "./command-context";
10
- import type { ArcCommandData, CommandProtection, CommandProtectionCheck } from "./command-data";
12
+ import type { ArcCommandData } from "./command-data";
11
13
  import type { ArcCommandHandler } from "./command-handler";
12
14
  /**
13
15
  * Arc Command - Business action that modifies state
14
16
  *
15
- * Commands are the primary way to execute business logic in Arc Framework.
16
- * They can:
17
- * - Accept typed parameters
18
- * - Return typed results
19
- * - Query state through query elements (views)
20
- * - Mutate state through mutation elements (events, other commands)
21
- *
22
- * Commands follow the factory pattern from the Arc guide:
23
- * - All configuration in a single Data object
24
- * - Type-safe throughout
25
- * - Immutable with clone-on-modify
26
- * - Separate query and mutation concerns
17
+ * Uses ArcFunction internally (#fn) for unified params, result, protection,
18
+ * and context dependency management.
27
19
  *
28
20
  * @example
29
21
  * ```typescript
30
22
  * const registerCmd = command("register")
31
- * .public()
32
23
  * .query([usersView])
33
24
  * .mutate([userRegisteredEvent])
34
25
  * .withParams({ email: string(), password: string() })
35
26
  * .withResult({ success: boolean() })
27
+ * .protectBy(adminToken, t => t.canI('register'))
36
28
  * .handle(async (ctx, params) => {
37
- * // Business logic here
38
29
  * return { success: true };
39
30
  * });
40
31
  * ```
41
32
  */
42
33
  export declare class ArcCommand<const Data extends ArcCommandData> extends ArcContextElement<Data["name"]> {
34
+ #private;
43
35
  private readonly data;
44
- constructor(data: Data);
45
- /**
46
- * Set command description for documentation and tooling
47
- */
36
+ constructor(data: Data, fn?: ArcFunction<any>);
48
37
  description<const Desc extends string>(description: Desc): ArcCommand<Merge<Data, {
49
38
  description: Desc;
50
39
  }>>;
51
- /**
52
- * Check if command is public (no protections = public)
53
- * Commands without protectBy() are considered public
54
- */
55
40
  get isPublic(): boolean;
56
- /**
57
- * Add query elements (views) that this command needs to read from
58
- * Query elements provide read-only access to state
59
- *
60
- * @param elements - Array of view elements to query
61
- */
62
41
  query<const Elements extends ArcContextElement<any>[]>(elements: Elements): ArcCommand<Merge<Data, {
63
42
  queryElements: Elements;
64
43
  }>>;
65
- /**
66
- * Add mutation elements (events, commands) that this command needs to modify state
67
- * Mutation elements provide write access to state
68
- *
69
- * @param elements - Array of event/command elements to mutate with
70
- */
71
44
  mutate<const Elements extends ArcContextElement<any>[]>(elements: Elements): ArcCommand<Merge<Data, {
72
45
  mutationElements: Elements;
73
46
  }>>;
74
- /**
75
- * Define command parameters schema
76
- *
77
- * @param schema - Object schema or raw shape defining parameter structure
78
- */
79
47
  withParams<NewParams extends ArcRawShape>(schema: NewParams | ArcObject<NewParams>): ArcCommand<Merge<Data, {
80
48
  params: ArcObject<NewParams>;
81
49
  }>>;
82
- /**
83
- * Define command result schemas
84
- * Commands can return multiple result types (success, error variants)
85
- *
86
- * @param schemas - Array of object schemas for possible results
87
- */
88
50
  withResult<NewResults extends ArcRawShape[]>(...schemas: NewResults): ArcCommand<Merge<Data, {
89
51
  results: { [K in keyof NewResults]: ArcObject<NewResults[K]>; };
90
52
  }>>;
91
- /**
92
- * Set command handler function
93
- * The handler contains the business logic for this command
94
- *
95
- * @param handler - Function that executes command logic, or false to disable
96
- */
97
53
  handle<Handler extends ArcCommandHandler<ArcCommandContextFromData<Data>, Data["params"] extends ArcObjectAny ? $type<Data["params"]> : null, $type<Data["results"][number]>> | false>(handler: Handler): ArcCommand<Merge<Data, {
98
54
  handler: Handler;
99
55
  }>>;
100
- /**
101
- * Add token-based protection to this command
102
- * Multiple protections can be added (all must pass)
103
- *
104
- * @param token - Token definition to protect with
105
- * @param check - Function to check if access is allowed
106
- *
107
- * @example
108
- * ```typescript
109
- * command("editForm")
110
- * .protectBy(moderatorToken, (token) => token.canI('form:edit'))
111
- * .handle(async (ctx, params) => { ... });
112
- * ```
113
- */
114
- protectBy<T extends ArcTokenAny>(token: T, check: CommandProtectionCheck<T>): ArcCommand<Merge<Data, {
115
- protections: [...Data["protections"] extends infer P extends CommandProtection[] ? P : [], {
56
+ protectBy<T extends ArcTokenAny>(token: T, check: FnProtectionCheck<T>): ArcCommand<Merge<Data, {
57
+ protections: [...Data["protections"] extends infer P extends FnProtection[] ? P : [], {
116
58
  token: T;
117
59
  check: typeof check;
118
60
  }];
119
61
  }>>;
120
- /**
121
- * Check if command has protections
122
- */
123
62
  get hasProtections(): boolean;
124
- /**
125
- * Get all protection configurations
126
- */
127
- get protections(): CommandProtection[];
128
- /**
129
- * Verify all protections pass for given token instances
130
- *
131
- * @param tokens - Array of token instances to verify
132
- * @returns true if all protections pass
133
- */
63
+ get protections(): FnProtection[];
134
64
  verifyProtections(tokens: TokenInstanceAny[]): Promise<boolean>;
135
- /**
136
- * Initialize command in the given environment
137
- * On server: registers command handler for remote execution
138
- */
139
65
  init(environment: import("../context-element").ArcEnvironment, adapters: ModelAdapters): Promise<void>;
140
- /**
141
- * Generate mutation context for this command
142
- * Provides execute functionality to run the command
143
- *
144
- * @param adapters - Available adapters (storage, commandWire, eventPublisher)
145
- * @returns Context object with execute method
146
- */
147
66
  mutateContext(adapters: ModelAdapters): ((params: Data["params"] extends ArcObjectAny ? $type<Data["params"]> : null) => Promise<$type<Data["results"][number]>>) & {
148
67
  params: Data["params"];
149
68
  };
150
- /**
151
- * Execute command locally with handler
152
- * Collects events and publishes them via eventPublisher
153
- */
154
69
  private executeLocally;
155
- /**
156
- * Build command context with access to query and mutation elements
157
- */
158
70
  private buildCommandContext;
159
- /**
160
- * Convert command to JSON Schema format
161
- * Used for OpenAPI documentation and validation
162
- */
163
71
  toJsonSchema(): {
164
72
  type: string;
165
73
  name: string;
@@ -168,21 +76,6 @@ export declare class ArcCommand<const Data extends ArcCommandData> extends ArcCo
168
76
  strict: boolean;
169
77
  };
170
78
  }
171
- /**
172
- * Create a new command with the given name
173
- *
174
- * @param name - Unique command name
175
- * @returns New command instance ready for configuration
176
- *
177
- * @example
178
- * ```typescript
179
- * const myCommand = command("myCommand")
180
- * .withParams({ input: string() })
181
- * .handle(async (ctx, params) => {
182
- * // logic here
183
- * });
184
- * ```
185
- */
186
79
  export declare function command<const Name extends string>(name: Name): ArcCommand<{
187
80
  readonly name: Name;
188
81
  readonly params: null;
@@ -191,8 +84,5 @@ export declare function command<const Name extends string>(name: Name): ArcComma
191
84
  readonly mutationElements: [];
192
85
  readonly protections: [];
193
86
  }>;
194
- /**
195
- * Type alias for any command (used in collections)
196
- */
197
87
  export type ArcCommandAny = ArcCommand<any>;
198
88
  //# sourceMappingURL=command.d.ts.map
@@ -1,5 +1,5 @@
1
1
  export { ArcCommand, command, type ArcCommandAny } from "./command";
2
- export type { ArcCommandContext, ArcCommandContextFromData, AuthContext, } from "./command-context";
2
+ export type { ArcCommandContext, ArcCommandContextFromData, } from "./command-context";
3
3
  export type { ArcCommandData, CommandProtection, CommandProtectionCheck, } from "./command-data";
4
4
  export type { ArcCommandHandler } from "./command-handler";
5
5
  export type { ArcObjectAny, ArcRawShape } from "../../elements/object";
@@ -2,37 +2,47 @@ import type { ModelAdapters } from "../model/model-adapters";
2
2
  import type { ArcContextElement } from "./context-element";
3
3
  /**
4
4
  * Query context — maps element names to their queryContext return types.
5
- * Uses key remapping to filter only elements that have queryContext.
6
5
  */
7
6
  type QueryContext<Elements extends ArcContextElement<any>[]> = {
8
7
  [K in Elements[number] as K["queryContext"] extends (...args: any) => any ? K["name"] : never]: K["queryContext"] extends (...args: any) => infer R ? R : never;
9
8
  };
10
9
  /**
11
10
  * Mutation context — maps element names to their mutateContext return types.
12
- * Uses key remapping to filter only elements that have mutateContext.
13
11
  */
14
12
  type MutationContext<Elements extends ArcContextElement<any>[]> = {
15
13
  [K in Elements[number] as K["mutateContext"] extends (...args: any) => any ? K["name"] : never]: K["mutateContext"] extends (...args: any) => infer R ? R : never;
16
14
  };
17
15
  /**
18
- * Unified element context shared between routes, commands, and any
19
- * handler that needs typed access to query/mutation elements.
16
+ * Callable accessorboth a function (for references) and an object (for named access).
20
17
  *
21
- * Elements are accessible by name (ctx.myView, ctx.myAggregate) or
22
- * by reference (ctx.query(element), ctx.mutate(element)).
18
+ * @example
19
+ * ```typescript
20
+ * // By name (declared in .query()/.mutate()):
21
+ * ctx.query.myMessages.getByConversation({ conversationId })
22
+ *
23
+ * // By reference (factories, dynamic elements):
24
+ * ctx.query(messageElement).getByConversation({ conversationId })
25
+ * ```
26
+ */
27
+ type QueryAccessor<Elements extends ArcContextElement<any>[]> = ((element: ArcContextElement<any>) => any) & QueryContext<Elements>;
28
+ type MutateAccessor<Elements extends ArcContextElement<any>[]> = ((element: ArcContextElement<any>) => any) & MutationContext<Elements>;
29
+ /**
30
+ * Unified element context — shared between routes, commands, listeners.
31
+ *
32
+ * Elements are accessible by name (ctx.query.myView) or
33
+ * by reference (ctx.query(element)).
23
34
  */
24
- export type ElementContext<QueryElements extends ArcContextElement<any>[], MutationElements extends ArcContextElement<any>[]> = QueryContext<QueryElements> & MutationContext<MutationElements> & {
25
- get: <T extends ArcContextElement<any>>(element: T) => any;
26
- query: <T extends ArcContextElement<any>>(element: T) => T extends {
27
- queryContext: (...args: any) => infer R;
28
- } ? R : never;
29
- mutate: <T extends ArcContextElement<any>>(element: T) => T extends {
30
- mutateContext: (...args: any) => infer R;
31
- } ? R : never;
35
+ export type ElementContext<QueryElements extends ArcContextElement<any>[], MutationElements extends ArcContextElement<any>[]> = {
36
+ query: QueryAccessor<QueryElements>;
37
+ mutate: MutateAccessor<MutationElements>;
38
+ $auth?: {
39
+ params: any;
40
+ tokenName: string;
41
+ };
32
42
  };
33
43
  /**
34
44
  * Build element context at runtime.
35
- * Shared implementation for routes, commands, etc.
45
+ * Shared implementation for routes, commands, listeners.
36
46
  */
37
47
  export declare function buildElementContext(queryElements: ArcContextElement<any>[], mutationElements: ArcContextElement<any>[], adapters: ModelAdapters): any;
38
48
  export {};