@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.
package/dist/index.js CHANGED
@@ -1697,6 +1697,165 @@ function event(name, payload) {
1697
1697
  });
1698
1698
  }
1699
1699
 
1700
+ // src/context-element/element-context.ts
1701
+ function buildElementContext(queryElements, mutationElements, adapters) {
1702
+ const queryMap = new Map;
1703
+ const mutateMap = new Map;
1704
+ const queryProps = {};
1705
+ for (const element of queryElements) {
1706
+ if (element.queryContext) {
1707
+ const ctx = element.queryContext(adapters);
1708
+ queryProps[element.name] = ctx;
1709
+ queryMap.set(element, ctx);
1710
+ }
1711
+ }
1712
+ const mutateProps = {};
1713
+ for (const element of mutationElements) {
1714
+ if (element.mutateContext) {
1715
+ const ctx = element.mutateContext(adapters);
1716
+ mutateProps[element.name] = ctx;
1717
+ mutateMap.set(element, ctx);
1718
+ }
1719
+ }
1720
+ const queryFn = (element) => {
1721
+ const cached = queryMap.get(element);
1722
+ if (cached)
1723
+ return cached;
1724
+ if (element.queryContext) {
1725
+ const ctx = element.queryContext(adapters);
1726
+ queryMap.set(element, ctx);
1727
+ return ctx;
1728
+ }
1729
+ throw new Error(`Element "${element.name}" has no queryContext`);
1730
+ };
1731
+ Object.assign(queryFn, queryProps);
1732
+ const mutateFn = (element) => {
1733
+ const cached = mutateMap.get(element);
1734
+ if (cached)
1735
+ return cached;
1736
+ if (element.mutateContext) {
1737
+ const ctx = element.mutateContext(adapters);
1738
+ mutateMap.set(element, ctx);
1739
+ return ctx;
1740
+ }
1741
+ throw new Error(`Element "${element.name}" has no mutateContext`);
1742
+ };
1743
+ Object.assign(mutateFn, mutateProps);
1744
+ return {
1745
+ query: queryFn,
1746
+ mutate: mutateFn
1747
+ };
1748
+ }
1749
+
1750
+ // src/context-element/function/arc-function.ts
1751
+ class ArcFunction {
1752
+ data;
1753
+ constructor(data) {
1754
+ this.data = data;
1755
+ }
1756
+ withParams(schema) {
1757
+ return new ArcFunction({
1758
+ ...this.data,
1759
+ params: schema instanceof ArcObject ? schema : new ArcObject(schema)
1760
+ });
1761
+ }
1762
+ withResult(schema) {
1763
+ return new ArcFunction({
1764
+ ...this.data,
1765
+ result: schema instanceof ArcObject ? schema : new ArcObject(schema)
1766
+ });
1767
+ }
1768
+ query(elements) {
1769
+ return new ArcFunction({
1770
+ ...this.data,
1771
+ queryElements: elements
1772
+ });
1773
+ }
1774
+ mutate(elements) {
1775
+ return new ArcFunction({
1776
+ ...this.data,
1777
+ mutationElements: elements
1778
+ });
1779
+ }
1780
+ protectedBy(token, check) {
1781
+ const existingProtections = this.data.protections || [];
1782
+ return new ArcFunction({
1783
+ ...this.data,
1784
+ protections: [...existingProtections, { token, check }]
1785
+ });
1786
+ }
1787
+ description(desc) {
1788
+ return new ArcFunction({
1789
+ ...this.data,
1790
+ description: desc
1791
+ });
1792
+ }
1793
+ handle(handler) {
1794
+ return new ArcFunction({
1795
+ ...this.data,
1796
+ handler
1797
+ });
1798
+ }
1799
+ get isPublic() {
1800
+ return !this.hasProtections;
1801
+ }
1802
+ get hasProtections() {
1803
+ return (this.data.protections?.length ?? 0) > 0;
1804
+ }
1805
+ get protections() {
1806
+ return this.data.protections || [];
1807
+ }
1808
+ get handler() {
1809
+ return this.data.handler;
1810
+ }
1811
+ get params() {
1812
+ return this.data.params;
1813
+ }
1814
+ get result() {
1815
+ return this.data.result;
1816
+ }
1817
+ async verifyProtections(tokens) {
1818
+ if (!this.data.protections || this.data.protections.length === 0) {
1819
+ return true;
1820
+ }
1821
+ for (const protection of this.data.protections) {
1822
+ const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
1823
+ if (!tokenInstance) {
1824
+ return false;
1825
+ }
1826
+ const result = await protection.check(tokenInstance);
1827
+ if (result === false) {
1828
+ return false;
1829
+ }
1830
+ }
1831
+ return true;
1832
+ }
1833
+ buildContext(adapters) {
1834
+ return buildElementContext(this.data.queryElements || [], this.data.mutationElements || [], adapters);
1835
+ }
1836
+ toJsonSchema() {
1837
+ return {
1838
+ params: this.data.params?.toJsonSchema?.() ?? null,
1839
+ result: this.data.result?.toJsonSchema?.() ?? null
1840
+ };
1841
+ }
1842
+ }
1843
+ var defaultFunctionData = {
1844
+ params: null,
1845
+ result: null,
1846
+ queryElements: [],
1847
+ mutationElements: [],
1848
+ protections: [],
1849
+ handler: null,
1850
+ description: undefined
1851
+ };
1852
+ function arcFunction() {
1853
+ return new ArcFunction(defaultFunctionData);
1854
+ }
1855
+ function arcFunctionWithCtx() {
1856
+ return new ArcFunction(defaultFunctionData);
1857
+ }
1858
+
1700
1859
  // src/context-element/aggregate/aggregate-base.ts
1701
1860
  class AggregateBase {
1702
1861
  value;
@@ -1797,12 +1956,13 @@ class ArcAggregateElement extends ArcContextElement {
1797
1956
  };
1798
1957
  return new ArcAggregateElement(this.name, this._id_factory, this.schema, [...this._events, entry], this._protections, this._mutateMethods, this._queryMethods, this._seeds);
1799
1958
  }
1800
- mutateMethod(methodName, config, handler) {
1801
- const paramsObj = config.params instanceof ArcObject ? config.params : new ArcObject(config.params);
1959
+ mutateMethod(methodName, configure) {
1960
+ const baseFn = arcFunctionWithCtx();
1961
+ const configuredFn = configure(baseFn);
1802
1962
  const entry = {
1803
1963
  name: methodName,
1804
- params: paramsObj,
1805
- handler
1964
+ params: configuredFn.data.params,
1965
+ handler: configuredFn.data.handler
1806
1966
  };
1807
1967
  return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, [...this._mutateMethods, entry], this._queryMethods, this._seeds);
1808
1968
  }
@@ -1811,13 +1971,18 @@ class ArcAggregateElement extends ArcContextElement {
1811
1971
  throw new Error("cron() must be called immediately after mutateMethod()");
1812
1972
  }
1813
1973
  const methods = [...this._mutateMethods];
1814
- methods[methods.length - 1] = { ...methods[methods.length - 1], cronExpression: expression };
1974
+ methods[methods.length - 1] = {
1975
+ ...methods[methods.length - 1],
1976
+ cronExpression: expression
1977
+ };
1815
1978
  return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, methods, this._queryMethods, this._seeds);
1816
1979
  }
1817
- clientQuery(methodName, handler) {
1980
+ clientQuery(methodName, configure) {
1981
+ const baseFn = arcFunctionWithCtx();
1982
+ const configuredFn = configure(baseFn);
1818
1983
  const entry = {
1819
1984
  name: methodName,
1820
- handler
1985
+ handler: configuredFn.data.handler
1821
1986
  };
1822
1987
  return new ArcAggregateElement(this.name, this._id_factory, this.schema, this._events, this._protections, this._mutateMethods, [...this._queryMethods, entry], this._seeds);
1823
1988
  }
@@ -1862,16 +2027,21 @@ class ArcAggregateElement extends ArcContextElement {
1862
2027
  static __aggregateCronMethods = cronMethods;
1863
2028
  static getEvent(eventName) {
1864
2029
  const entry = events.find((e) => e.isPublic && e.event.name === eventName);
1865
- return entry?.event;
2030
+ if (!entry)
2031
+ return;
2032
+ return Object.assign(Object.create(Object.getPrototypeOf(entry.event)), entry.event, { name: `${name}.${entry.event.name}` });
1866
2033
  }
1867
2034
  };
1868
- Object.defineProperty(AggregateClass, "name", { value: `${name}Aggregate` });
2035
+ Object.defineProperty(AggregateClass, "name", {
2036
+ value: `${name}Aggregate`
2037
+ });
1869
2038
  return AggregateClass;
1870
2039
  }
1871
2040
  getHandlers() {
1872
2041
  const handlers = {};
1873
2042
  for (const entry of this._events) {
1874
- handlers[entry.event.name] = entry.handler;
2043
+ const key = entry.isInline ? `${this.name}.${entry.event.name}` : entry.event.name;
2044
+ handlers[key] = entry.handler;
1875
2045
  }
1876
2046
  return handlers;
1877
2047
  }
@@ -1880,7 +2050,9 @@ class ArcAggregateElement extends ArcContextElement {
1880
2050
  }
1881
2051
  getEvent(eventName) {
1882
2052
  const entry = this._events.find((e) => e.isPublic && e.event.name === eventName);
1883
- return entry?.event;
2053
+ if (!entry)
2054
+ return;
2055
+ return Object.assign(Object.create(Object.getPrototypeOf(entry.event)), entry.event, { name: `${this.name}.${entry.event.name}` });
1884
2056
  }
1885
2057
  get cronMethods() {
1886
2058
  const result = [];
@@ -1901,9 +2073,16 @@ class ArcAggregateElement extends ArcContextElement {
1901
2073
  const AggCtor = this.Aggregate;
1902
2074
  const result = {};
1903
2075
  for (const method of this._queryMethods) {
2076
+ if (!method.handler)
2077
+ continue;
2078
+ const handler = method.handler;
1904
2079
  result[method.name] = (...args) => {
1905
- const ctx = { $query: privateQuery, $auth: auth, Aggregate: AggCtor };
1906
- return method.handler(ctx, ...args);
2080
+ const ctx = {
2081
+ $query: privateQuery,
2082
+ $auth: auth,
2083
+ Aggregate: AggCtor
2084
+ };
2085
+ return handler(ctx, ...args);
1907
2086
  };
1908
2087
  }
1909
2088
  return result;
@@ -2020,13 +2199,15 @@ class ArcAggregateElement extends ArcContextElement {
2020
2199
  const ctx = {};
2021
2200
  for (const entry of events) {
2022
2201
  const arcEvent = entry.event;
2202
+ if (!entry.isInline)
2203
+ continue;
2023
2204
  ctx[arcEvent.name] = {
2024
2205
  emit: async (payload) => {
2025
2206
  if (!adapters.eventPublisher) {
2026
2207
  throw new Error(`Cannot emit event "${arcEvent.name}": no eventPublisher adapter available`);
2027
2208
  }
2028
2209
  const eventInstance = {
2029
- type: arcEvent.name,
2210
+ type: `${aggregateName}.${arcEvent.name}`,
2030
2211
  payload,
2031
2212
  id: `${Date.now()}_${Math.random().toString(36).slice(2)}`,
2032
2213
  createdAt: new Date
@@ -2046,7 +2227,10 @@ class ArcAggregateElement extends ArcContextElement {
2046
2227
  if (!adapters.commandWire) {
2047
2228
  throw new Error(`Method "${method.name}" is server-only but no commandWire (WebSocket) is available.`);
2048
2229
  }
2049
- const wireAuth = adapters.scope ? { scope: adapters.scope.scopeName, token: adapters.scope.getToken() } : undefined;
2230
+ const wireAuth = adapters.scope ? {
2231
+ scope: adapters.scope.scopeName,
2232
+ token: adapters.scope.getToken()
2233
+ } : undefined;
2050
2234
  return adapters.commandWire.executeCommand(`${aggregateName}.${method.name}`, params, wireAuth);
2051
2235
  }
2052
2236
  const ctx = buildMutateMethodCtx();
@@ -2078,129 +2262,71 @@ function aggregate(name, id2, schema) {
2078
2262
  const schemaObj = schema instanceof ArcObject ? schema : new ArcObject(schema);
2079
2263
  return new ArcAggregateElement(name, id2, schemaObj);
2080
2264
  }
2081
- // src/context-element/element-context.ts
2082
- function buildElementContext(queryElements, mutationElements, adapters) {
2083
- const context2 = {};
2084
- const elementMap = new Map;
2085
- for (const element of queryElements) {
2086
- if (element.queryContext) {
2087
- const ctx = element.queryContext(adapters);
2088
- context2[element.name] = ctx;
2089
- elementMap.set(element, ctx);
2090
- }
2091
- }
2092
- for (const element of mutationElements) {
2093
- if (element.mutateContext) {
2094
- const ctx = element.mutateContext(adapters);
2095
- context2[element.name] = ctx;
2096
- elementMap.set(element, ctx);
2097
- }
2098
- }
2099
- context2.get = (element) => {
2100
- const cached = elementMap.get(element);
2101
- if (cached)
2102
- return cached;
2103
- if (element.queryContext) {
2104
- const ctx = element.queryContext(adapters);
2105
- elementMap.set(element, ctx);
2106
- return ctx;
2107
- }
2108
- if (element.mutateContext) {
2109
- const ctx = element.mutateContext(adapters);
2110
- elementMap.set(element, ctx);
2111
- return ctx;
2112
- }
2113
- throw new Error(`Element "${element.name}" has no context available`);
2114
- };
2115
- context2.query = (element) => {
2116
- if (!element.queryContext) {
2117
- throw new Error(`Element "${element.name}" has no queryContext`);
2118
- }
2119
- return element.queryContext(adapters);
2120
- };
2121
- context2.mutate = (element) => {
2122
- if (!element.mutateContext) {
2123
- throw new Error(`Element "${element.name}" has no mutateContext`);
2124
- }
2125
- return element.mutateContext(adapters);
2126
- };
2127
- return context2;
2128
- }
2129
-
2130
2265
  // src/context-element/command/command.ts
2131
2266
  class ArcCommand extends ArcContextElement {
2132
2267
  data;
2133
- constructor(data) {
2268
+ #fn;
2269
+ constructor(data, fn) {
2134
2270
  super(data.name);
2135
2271
  this.data = data;
2272
+ this.#fn = fn ?? new ArcFunction({
2273
+ params: data.params,
2274
+ result: null,
2275
+ queryElements: data.queryElements,
2276
+ mutationElements: data.mutationElements,
2277
+ protections: data.protections || [],
2278
+ handler: data.handler ?? null,
2279
+ description: data.description
2280
+ });
2136
2281
  }
2137
2282
  description(description) {
2138
- return new ArcCommand({
2139
- ...this.data,
2140
- description
2141
- });
2283
+ const newFn = this.#fn.description(description);
2284
+ return new ArcCommand({ ...this.data, description }, newFn);
2142
2285
  }
2143
2286
  get isPublic() {
2144
- return !this.hasProtections;
2287
+ return this.#fn.isPublic;
2145
2288
  }
2146
2289
  query(elements) {
2147
- return new ArcCommand({
2148
- ...this.data,
2149
- queryElements: elements
2150
- });
2290
+ const newFn = this.#fn.query(elements);
2291
+ return new ArcCommand({ ...this.data, queryElements: elements }, newFn);
2151
2292
  }
2152
2293
  mutate(elements) {
2153
- return new ArcCommand({
2154
- ...this.data,
2155
- mutationElements: elements
2156
- });
2294
+ const newFn = this.#fn.mutate(elements);
2295
+ return new ArcCommand({ ...this.data, mutationElements: elements }, newFn);
2157
2296
  }
2158
2297
  withParams(schema) {
2298
+ const newFn = this.#fn.withParams(schema);
2159
2299
  return new ArcCommand({
2160
2300
  ...this.data,
2161
2301
  params: schema instanceof ArcObject ? schema : new ArcObject(schema)
2162
- });
2302
+ }, newFn);
2163
2303
  }
2164
2304
  withResult(...schemas) {
2165
- return new ArcCommand({
2166
- ...this.data,
2167
- results: schemas
2168
- });
2305
+ return new ArcCommand({ ...this.data, results: schemas }, this.#fn);
2169
2306
  }
2170
2307
  handle(handler) {
2171
- return new ArcCommand({
2172
- ...this.data,
2308
+ const newFn = new ArcFunction({
2309
+ ...this.#fn.data,
2173
2310
  handler
2174
2311
  });
2312
+ return new ArcCommand({ ...this.data, handler }, newFn);
2175
2313
  }
2176
2314
  protectBy(token, check) {
2315
+ const newFn = this.#fn.protectedBy(token, check);
2177
2316
  const existingProtections = this.data.protections || [];
2178
2317
  return new ArcCommand({
2179
2318
  ...this.data,
2180
2319
  protections: [...existingProtections, { token, check }]
2181
- });
2320
+ }, newFn);
2182
2321
  }
2183
2322
  get hasProtections() {
2184
- return (this.data.protections?.length ?? 0) > 0;
2323
+ return this.#fn.hasProtections;
2185
2324
  }
2186
2325
  get protections() {
2187
- return this.data.protections || [];
2326
+ return this.#fn.protections;
2188
2327
  }
2189
2328
  async verifyProtections(tokens) {
2190
- if (!this.data.protections || this.data.protections.length === 0) {
2191
- return true;
2192
- }
2193
- for (const protection of this.data.protections) {
2194
- const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
2195
- if (!tokenInstance) {
2196
- return false;
2197
- }
2198
- const allowed = await protection.check(tokenInstance);
2199
- if (!allowed) {
2200
- return false;
2201
- }
2202
- }
2203
- return true;
2329
+ return this.#fn.verifyProtections(tokens);
2204
2330
  }
2205
2331
  async init(environment, adapters) {
2206
2332
  if (environment === "server" && this.data.handler && adapters.commandWire?.registerCommandHandler) {
@@ -2227,12 +2353,11 @@ class ArcCommand extends ArcContextElement {
2227
2353
  throw new Error(`Command "${this.data.name}" has no handler`);
2228
2354
  }
2229
2355
  const context2 = this.buildCommandContext(adapters);
2230
- const result = await this.data.handler(context2, params);
2231
- return result;
2356
+ return await this.data.handler(context2, params);
2232
2357
  }
2233
2358
  buildCommandContext(adapters) {
2234
- const context2 = buildElementContext(this.data.queryElements, this.data.mutationElements, adapters);
2235
- if (this.hasProtections && adapters.authAdapter) {
2359
+ const context2 = this.#fn.buildContext(adapters);
2360
+ if (this.#fn.hasProtections && adapters.authAdapter) {
2236
2361
  const decoded = adapters.authAdapter.getDecoded();
2237
2362
  if (decoded) {
2238
2363
  context2.$auth = {
@@ -2272,46 +2397,41 @@ function command(name) {
2272
2397
  // src/context-element/listener/listener.ts
2273
2398
  class ArcListener extends ArcContextElement {
2274
2399
  data;
2400
+ #fn;
2275
2401
  unsubscribers = [];
2276
- constructor(data) {
2402
+ constructor(data, fn) {
2277
2403
  super(data.name);
2278
2404
  this.data = data;
2405
+ this.#fn = fn ?? new ArcFunction({
2406
+ params: null,
2407
+ result: null,
2408
+ queryElements: data.queryElements,
2409
+ mutationElements: data.mutationElements,
2410
+ protections: [],
2411
+ handler: null,
2412
+ description: data.description
2413
+ });
2279
2414
  }
2280
2415
  description(description) {
2281
- return new ArcListener({
2282
- ...this.data,
2283
- description
2284
- });
2416
+ const newFn = this.#fn.description(description);
2417
+ return new ArcListener({ ...this.data, description }, newFn);
2285
2418
  }
2286
2419
  listenTo(events) {
2287
- return new ArcListener({
2288
- ...this.data,
2289
- eventElements: events
2290
- });
2420
+ return new ArcListener({ ...this.data, eventElements: events }, this.#fn);
2291
2421
  }
2292
2422
  query(elements) {
2293
- return new ArcListener({
2294
- ...this.data,
2295
- queryElements: elements
2296
- });
2423
+ const newFn = this.#fn.query(elements);
2424
+ return new ArcListener({ ...this.data, queryElements: elements }, newFn);
2297
2425
  }
2298
2426
  mutate(elements) {
2299
- return new ArcListener({
2300
- ...this.data,
2301
- mutationElements: elements
2302
- });
2427
+ const newFn = this.#fn.mutate(elements);
2428
+ return new ArcListener({ ...this.data, mutationElements: elements }, newFn);
2303
2429
  }
2304
2430
  async() {
2305
- return new ArcListener({
2306
- ...this.data,
2307
- isAsync: true
2308
- });
2431
+ return new ArcListener({ ...this.data, isAsync: true }, this.#fn);
2309
2432
  }
2310
2433
  handle(handler) {
2311
- return new ArcListener({
2312
- ...this.data,
2313
- handler
2314
- });
2434
+ return new ArcListener({ ...this.data, handler }, this.#fn);
2315
2435
  }
2316
2436
  get eventElements() {
2317
2437
  return this.data.eventElements || [];
@@ -2341,48 +2461,7 @@ class ArcListener extends ArcContextElement {
2341
2461
  async handleEvent(event2, adapters) {
2342
2462
  if (!this.data.handler)
2343
2463
  return;
2344
- const context2 = this.buildListenerContext(adapters);
2345
- if (this.data.isAsync) {
2346
- Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
2347
- console.error(`Async listener "${this.data.name}" error:`, error);
2348
- });
2349
- } else {
2350
- await this.data.handler(context2, event2);
2351
- }
2352
- }
2353
- buildListenerContext(adapters) {
2354
- const context2 = {};
2355
- const elementMap = new Map;
2356
- for (const element of this.data.queryElements) {
2357
- if (element.queryContext) {
2358
- const elementContext = element.queryContext(adapters);
2359
- context2[element.name] = elementContext;
2360
- elementMap.set(element, elementContext);
2361
- }
2362
- }
2363
- for (const element of this.data.mutationElements) {
2364
- if (element.mutateContext) {
2365
- const elementContext = element.mutateContext(adapters);
2366
- context2[element.name] = elementContext;
2367
- elementMap.set(element, elementContext);
2368
- }
2369
- }
2370
- context2.get = (element) => {
2371
- const cached = elementMap.get(element);
2372
- if (cached)
2373
- return cached;
2374
- if (element.queryContext) {
2375
- const ctx = element.queryContext(adapters);
2376
- elementMap.set(element, ctx);
2377
- return ctx;
2378
- }
2379
- if (element.mutateContext) {
2380
- const ctx = element.mutateContext(adapters);
2381
- elementMap.set(element, ctx);
2382
- return ctx;
2383
- }
2384
- throw new Error(`Element "${element.name}" has no context available`);
2385
- };
2464
+ const context2 = this.#fn.buildContext(adapters);
2386
2465
  if (adapters.authAdapter) {
2387
2466
  const decoded = adapters.authAdapter.getDecoded();
2388
2467
  if (decoded) {
@@ -2392,7 +2471,13 @@ class ArcListener extends ArcContextElement {
2392
2471
  };
2393
2472
  }
2394
2473
  }
2395
- return context2;
2474
+ if (this.data.isAsync) {
2475
+ Promise.resolve(this.data.handler(context2, event2)).catch((error) => {
2476
+ console.error(`Async listener "${this.data.name}" error:`, error);
2477
+ });
2478
+ } else {
2479
+ await this.data.handler(context2, event2);
2480
+ }
2396
2481
  }
2397
2482
  destroy() {
2398
2483
  for (const unsubscribe of this.unsubscribers) {
@@ -2413,52 +2498,48 @@ function listener(name) {
2413
2498
  // src/context-element/route/route.ts
2414
2499
  class ArcRoute extends ArcContextElement {
2415
2500
  data;
2416
- constructor(data) {
2501
+ #fn;
2502
+ constructor(data, fn) {
2417
2503
  super(data.name);
2418
2504
  this.data = data;
2505
+ this.#fn = fn ?? new ArcFunction({
2506
+ params: null,
2507
+ result: null,
2508
+ queryElements: data.queryElements,
2509
+ mutationElements: data.mutationElements,
2510
+ protections: data.protections || [],
2511
+ handler: null,
2512
+ description: data.description
2513
+ });
2419
2514
  }
2420
2515
  description(description) {
2421
- return new ArcRoute({
2422
- ...this.data,
2423
- description
2424
- });
2516
+ const newFn = this.#fn.description(description);
2517
+ return new ArcRoute({ ...this.data, description }, newFn);
2425
2518
  }
2426
2519
  path(path) {
2427
- return new ArcRoute({
2428
- ...this.data,
2429
- path
2430
- });
2520
+ return new ArcRoute({ ...this.data, path }, this.#fn);
2431
2521
  }
2432
2522
  public() {
2433
- return new ArcRoute({
2434
- ...this.data,
2435
- isPublic: true
2436
- });
2523
+ return new ArcRoute({ ...this.data, isPublic: true }, this.#fn);
2437
2524
  }
2438
2525
  query(elements) {
2439
- return new ArcRoute({
2440
- ...this.data,
2441
- queryElements: elements
2442
- });
2526
+ const newFn = this.#fn.query(elements);
2527
+ return new ArcRoute({ ...this.data, queryElements: elements }, newFn);
2443
2528
  }
2444
2529
  mutate(elements) {
2445
- return new ArcRoute({
2446
- ...this.data,
2447
- mutationElements: elements
2448
- });
2530
+ const newFn = this.#fn.mutate(elements);
2531
+ return new ArcRoute({ ...this.data, mutationElements: elements }, newFn);
2449
2532
  }
2450
2533
  protectBy(token, check) {
2534
+ const newFn = this.#fn.protectedBy(token, check);
2451
2535
  const existingProtections = this.data.protections || [];
2452
2536
  return new ArcRoute({
2453
2537
  ...this.data,
2454
2538
  protections: [...existingProtections, { token, check }]
2455
- });
2539
+ }, newFn);
2456
2540
  }
2457
2541
  handle(handlers) {
2458
- return new ArcRoute({
2459
- ...this.data,
2460
- handlers
2461
- });
2542
+ return new ArcRoute({ ...this.data, handlers }, this.#fn);
2462
2543
  }
2463
2544
  get routePath() {
2464
2545
  return this.data.path || `/${this.data.name}`;
@@ -2470,7 +2551,7 @@ class ArcRoute extends ArcContextElement {
2470
2551
  return this.data.isPublic;
2471
2552
  }
2472
2553
  get hasProtections() {
2473
- return (this.data.protections?.length ?? 0) > 0;
2554
+ return this.#fn.hasProtections;
2474
2555
  }
2475
2556
  get protections() {
2476
2557
  return this.data.protections || [];
@@ -2502,23 +2583,10 @@ class ArcRoute extends ArcContextElement {
2502
2583
  if (this.data.isPublic) {
2503
2584
  return true;
2504
2585
  }
2505
- if (!this.data.protections || this.data.protections.length === 0) {
2506
- return true;
2507
- }
2508
- for (const protection of this.data.protections) {
2509
- const tokenInstance = tokens.find((t) => t.getTokenDefinition() === protection.token);
2510
- if (!tokenInstance) {
2511
- return false;
2512
- }
2513
- const allowed = await protection.check(tokenInstance);
2514
- if (!allowed) {
2515
- return false;
2516
- }
2517
- }
2518
- return true;
2586
+ return this.#fn.verifyProtections(tokens);
2519
2587
  }
2520
2588
  buildContext(adapters, authParams) {
2521
- const context2 = buildElementContext(this.data.queryElements, this.data.mutationElements, adapters);
2589
+ const context2 = this.#fn.buildContext(adapters);
2522
2590
  if (authParams) {
2523
2591
  context2.$auth = authParams;
2524
2592
  }
@@ -2972,6 +3040,8 @@ function deepMerge(target, source) {
2972
3040
  function isPlainObject(item) {
2973
3041
  return item && typeof item === "object" && !Array.isArray(item) && !(item instanceof Date) && Object.prototype.toString.call(item) === "[object Object]";
2974
3042
  }
3043
+ // src/utils/merge-unsafe.ts
3044
+ var mergeUnsafe = (schema, unsafeSchema) => Object.assign({}, schema, unsafeSchema);
2975
3045
  // src/utils/murmur-hash.ts
2976
3046
  function murmurHash(key, seed = 0) {
2977
3047
  let remainder, bytes, h1, h1b, c1, c2, k1, i;
@@ -5010,12 +5080,14 @@ export {
5010
5080
  number,
5011
5081
  mutationExecutor,
5012
5082
  murmurHash,
5083
+ mergeUnsafe,
5013
5084
  listener,
5014
5085
  id,
5015
5086
  file,
5016
5087
  extractDatabaseAgnosticSchema,
5017
5088
  executeDescriptor,
5018
5089
  event,
5090
+ defaultFunctionData,
5019
5091
  deepMerge,
5020
5092
  date,
5021
5093
  customId,
@@ -5028,6 +5100,8 @@ export {
5028
5100
  boolean,
5029
5101
  blob,
5030
5102
  array,
5103
+ arcFunctionWithCtx,
5104
+ arcFunction,
5031
5105
  applyOrderByAndLimit,
5032
5106
  any,
5033
5107
  aggregate,
@@ -5066,6 +5140,7 @@ export {
5066
5140
  ArcNumber,
5067
5141
  ArcListener,
5068
5142
  ArcId,
5143
+ ArcFunction,
5069
5144
  ArcFragmentBase,
5070
5145
  ArcFile,
5071
5146
  ArcEvent,