akanjs 3.0.0-alpha.99 → 3.0.0-beta.0

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.
Files changed (270) hide show
  1. package/client/csrTypes.ts +3 -0
  2. package/client/index.ts +1 -0
  3. package/client/route/LayoutDefinition.ts +46 -0
  4. package/client/route/PageDefinition.ts +53 -0
  5. package/client/route/RootLayoutDefinition.ts +58 -0
  6. package/client/route/RouteDefinition.ts +204 -0
  7. package/client/route/index.ts +7 -0
  8. package/client/route/resolveRouteModule.ts +46 -0
  9. package/client/route/routeArgs.ts +51 -0
  10. package/client/route/routeBuilders.ts +10 -0
  11. package/common/TrustedProxy.ts +23 -1
  12. package/common/index.ts +0 -1
  13. package/common/mcpExposure.ts +5 -22
  14. package/constant/cascadePaths.ts +20 -20
  15. package/constant/deserialize.ts +30 -3
  16. package/constant/fieldInfo.ts +22 -16
  17. package/constant/purify.ts +2 -0
  18. package/constant/types.ts +6 -2
  19. package/dictionary/base.dictionary.ts +1 -0
  20. package/document/documentSchema.ts +20 -0
  21. package/document/filterMeta.ts +21 -0
  22. package/document/into.ts +0 -8
  23. package/fetch/client/fetchClient.ts +17 -8
  24. package/fetch/client/httpClient.ts +2 -30
  25. package/fetch/client/index.ts +1 -0
  26. package/fetch/client/remoteError.ts +57 -0
  27. package/fetch/client/wsClient.ts +2 -9
  28. package/fetch/requestStorage.ts +15 -0
  29. package/local/apps/serverLifecycle/serverLifecycle-local.db-shm +0 -0
  30. package/local/apps/serverLifecycle/serverLifecycle-local_solid.db-shm +0 -0
  31. package/package.json +1 -1
  32. package/server/akanApp.ts +21 -1
  33. package/server/akanAppHeaders.ts +1 -1
  34. package/server/akanOption.ts +7 -6
  35. package/server/akanServer.ts +78 -7
  36. package/server/di/diLifecycle.ts +108 -7
  37. package/server/di/utils.ts +1 -1
  38. package/server/index.ts +1 -0
  39. package/server/mcp/McpAuth.ts +107 -29
  40. package/server/mcp/McpDispatcher.ts +6 -40
  41. package/server/mcp/McpExecutionContext.ts +6 -1
  42. package/server/mcp/McpRateLimiter.ts +88 -0
  43. package/server/mcp/McpRouter.ts +226 -50
  44. package/server/mcp/PagePromptComposer.ts +205 -0
  45. package/server/mcp/index.ts +1 -0
  46. package/server/oauth/OAuthAuthorize.ts +84 -0
  47. package/server/oauth/OAuthClientIdMetadata.ts +139 -0
  48. package/server/oauth/OAuthErrors.ts +77 -0
  49. package/server/oauth/OAuthMetadata.ts +59 -0
  50. package/server/oauth/OAuthPkce.ts +29 -0
  51. package/server/oauth/OAuthRedirect.ts +57 -0
  52. package/server/oauth/OAuthRegistration.ts +86 -0
  53. package/server/oauth/OAuthRevocation.ts +60 -0
  54. package/server/oauth/OAuthToken.ts +115 -0
  55. package/server/oauth/index.ts +10 -0
  56. package/server/oauth/oauthTypes.ts +79 -0
  57. package/server/resolver/CascadeRunner.ts +1 -1
  58. package/server/resolver/database.resolver.ts +70 -72
  59. package/server/resolver/service.resolver.ts +4 -14
  60. package/server/resolver/signal.resolver.ts +0 -8
  61. package/server/routeTreeBuilder.ts +45 -19
  62. package/server/routing/apiRouter.ts +1 -15
  63. package/server/rscPagePrompts.ts +175 -0
  64. package/server/rscWorker.tsx +41 -1
  65. package/server/rscWorkerHost.ts +54 -0
  66. package/server/webRouter.ts +9 -0
  67. package/service/agent.service.ts +31 -1
  68. package/service/predefinedAdaptor/deepseekLlm.ts +1 -0
  69. package/service/predefinedAdaptor/llm.adaptor.ts +2 -0
  70. package/signal/endpointInfo.ts +2 -38
  71. package/signal/exception.ts +18 -0
  72. package/signal/guard.ts +14 -1
  73. package/signal/mcp/McpDocument.ts +51 -69
  74. package/signal/mcp/McpUriTemplate.ts +22 -0
  75. package/signal/mcp/index.ts +2 -1
  76. package/signal/mcp/mcpProtocol.ts +2 -0
  77. package/signal/mcp/pagePrompt.ts +45 -0
  78. package/signal/openapi/openapi.ts +4 -19
  79. package/signal/schema/JsonSchemaBuilder.ts +55 -18
  80. package/signal/serializer/fetch.serializer.ts +15 -0
  81. package/signal/signalContext.ts +49 -29
  82. package/signal/types.ts +8 -1
  83. package/store/action.ts +15 -12
  84. package/store/agent/AgentBridge.ts +10 -2
  85. package/store/agent/AgentPrompts.ts +4 -57
  86. package/store/agent/ScreenReader.ts +31 -6
  87. package/store/agent/StoreSurfaceSource.ts +13 -4
  88. package/store/agentic/StToolBuilder.ts +49 -22
  89. package/store/agentic/formFields.ts +21 -0
  90. package/store/agentic/index.ts +1 -0
  91. package/store/agentic/useFileFieldTool.ts +221 -0
  92. package/store/agentic/useRelationFieldTool.ts +3 -13
  93. package/types/client/csrTypes.d.ts +3 -0
  94. package/types/client/index.d.ts +1 -0
  95. package/types/client/route/LayoutDefinition.d.ts +16 -0
  96. package/types/client/route/PageDefinition.d.ts +15 -0
  97. package/types/client/route/RootLayoutDefinition.d.ts +17 -0
  98. package/types/client/route/RouteDefinition.d.ts +46 -0
  99. package/types/client/route/index.d.ts +7 -0
  100. package/types/client/route/resolveRouteModule.d.ts +24 -0
  101. package/types/client/route/routeArgs.d.ts +40 -0
  102. package/types/client/route/routeBuilders.d.ts +9 -0
  103. package/types/client/route.d.ts +1 -0
  104. package/types/common/TrustedProxy.d.ts +12 -0
  105. package/types/common/index.d.ts +1 -1
  106. package/types/common/mcpExposure.d.ts +2 -7
  107. package/types/constant/cascadePaths.d.ts +4 -2
  108. package/types/constant/deserialize.d.ts +6 -3
  109. package/types/constant/fieldInfo.d.ts +15 -8
  110. package/types/constant/types.d.ts +5 -2
  111. package/types/dictionary/base.dictionary.d.ts +1 -1
  112. package/types/dictionary/dictionary.d.ts +8 -8
  113. package/types/document/documentSchema.d.ts +2 -0
  114. package/types/document/filterMeta.d.ts +8 -0
  115. package/types/document/into.d.ts +0 -8
  116. package/types/fetch/client/fetchClient.d.ts +2 -1
  117. package/types/fetch/client/httpClient.d.ts +1 -19
  118. package/types/fetch/client/index.d.ts +1 -0
  119. package/types/fetch/client/remoteError.d.ts +31 -0
  120. package/types/fetch/client/wsClient.d.ts +1 -1
  121. package/types/fetch/requestStorage.d.ts +15 -0
  122. package/types/server/akanApp.d.ts +11 -0
  123. package/types/server/akanOption.d.ts +4 -3
  124. package/types/server/akanServer.d.ts +33 -1
  125. package/types/server/di/diLifecycle.d.ts +12 -1
  126. package/types/server/di/utils.d.ts +1 -1
  127. package/types/server/index.d.ts +1 -0
  128. package/types/server/mcp/McpAuth.d.ts +52 -13
  129. package/types/server/mcp/McpDispatcher.d.ts +1 -13
  130. package/types/server/mcp/McpRateLimiter.d.ts +38 -0
  131. package/types/server/mcp/McpRouter.d.ts +17 -0
  132. package/types/server/mcp/PagePromptComposer.d.ts +34 -0
  133. package/types/server/mcp/index.d.ts +1 -0
  134. package/types/server/oauth/OAuthAuthorize.d.ts +26 -0
  135. package/types/server/oauth/OAuthClientIdMetadata.d.ts +53 -0
  136. package/types/server/oauth/OAuthErrors.d.ts +40 -0
  137. package/types/server/oauth/OAuthMetadata.d.ts +37 -0
  138. package/types/server/oauth/OAuthPkce.d.ts +9 -0
  139. package/types/server/oauth/OAuthRedirect.d.ts +20 -0
  140. package/types/server/oauth/OAuthRegistration.d.ts +21 -0
  141. package/types/server/oauth/OAuthRevocation.d.ts +31 -0
  142. package/types/server/oauth/OAuthToken.d.ts +35 -0
  143. package/types/server/oauth/index.d.ts +10 -0
  144. package/types/server/oauth/oauthTypes.d.ts +49 -0
  145. package/types/server/oauth.d.ts +1 -0
  146. package/types/server/routeTreeBuilder.d.ts +5 -2
  147. package/types/server/rscPagePrompts.d.ts +26 -0
  148. package/types/server/rscWorkerHost.d.ts +3 -0
  149. package/types/server/webRouter.d.ts +3 -0
  150. package/types/service/agent.service.d.ts +19 -0
  151. package/types/service/predefinedAdaptor/llm.adaptor.d.ts +2 -0
  152. package/types/signal/endpointInfo.d.ts +3 -21
  153. package/types/signal/exception.d.ts +11 -0
  154. package/types/signal/guard.d.ts +9 -0
  155. package/types/signal/mcp/McpDocument.d.ts +19 -11
  156. package/types/signal/mcp/McpUriTemplate.d.ts +6 -0
  157. package/types/signal/mcp/index.d.ts +2 -1
  158. package/types/signal/mcp/mcpProtocol.d.ts +2 -0
  159. package/types/signal/mcp/pagePrompt.d.ts +50 -0
  160. package/types/signal/schema/JsonSchemaBuilder.d.ts +24 -3
  161. package/types/signal/signalContext.d.ts +6 -0
  162. package/types/signal/types.d.ts +8 -1
  163. package/types/store/action.d.ts +2 -2
  164. package/types/store/agent/AgentPrompts.d.ts +4 -17
  165. package/types/store/agent/ScreenReader.d.ts +10 -2
  166. package/types/store/agentic/StToolBuilder.d.ts +18 -7
  167. package/types/store/agentic/formFields.d.ts +12 -0
  168. package/types/store/agentic/index.d.ts +1 -0
  169. package/types/store/agentic/useFileFieldTool.d.ts +41 -0
  170. package/types/store/agentic/useRelationFieldTool.d.ts +1 -1
  171. package/types/ui/Agent/Chat.d.ts +8 -2
  172. package/types/ui/Agent/ChatCommands.d.ts +2 -4
  173. package/types/ui/Agent/attachment.d.ts +25 -4
  174. package/types/ui/Agent/useChatAttachments.d.ts +3 -2
  175. package/types/ui/Agent/useChatQueue.d.ts +3 -1
  176. package/types/ui/Agent/useSlashMenu.d.ts +2 -8
  177. package/types/ui/BottomSheet.d.ts +15 -2
  178. package/types/ui/CsrImage.d.ts +2 -2
  179. package/types/ui/Data/ListContainer.d.ts +1 -1
  180. package/types/ui/Dialog/Modal.d.ts +3 -1
  181. package/types/ui/Dialog/index.d.ts +1 -1
  182. package/types/ui/Dropdown.d.ts +5 -3
  183. package/types/ui/Empty.d.ts +3 -1
  184. package/types/ui/Field/Label.d.ts +4 -3
  185. package/types/ui/Field/index.d.ts +2 -2
  186. package/types/ui/Image.d.ts +3 -3
  187. package/types/ui/InfiniteScroll.d.ts +4 -1
  188. package/types/ui/Layout/BottomTab.d.ts +4 -2
  189. package/types/ui/Layout/LeftSider.d.ts +3 -1
  190. package/types/ui/Layout/RightSider.d.ts +4 -2
  191. package/types/ui/Layout/Sider.d.ts +7 -1
  192. package/types/ui/Layout/index.d.ts +4 -4
  193. package/types/ui/Load/Units.d.ts +3 -1
  194. package/types/ui/Load/View.d.ts +3 -1
  195. package/types/ui/Loading/Area.d.ts +9 -1
  196. package/types/ui/Menu.d.ts +3 -1
  197. package/types/ui/Modal.d.ts +7 -3
  198. package/types/ui/Model/Edit.d.ts +2 -4
  199. package/types/ui/Model/EditModal.d.ts +1 -1
  200. package/types/ui/Model/New.d.ts +2 -4
  201. package/types/ui/Model/Remove.d.ts +7 -1
  202. package/types/ui/Model/SureToRemove.d.ts +10 -1
  203. package/types/ui/Model/ViewEditModal.d.ts +7 -1
  204. package/types/ui/Pagination.d.ts +10 -2
  205. package/types/ui/Popconfirm.d.ts +8 -4
  206. package/types/ui/Select.d.ts +5 -3
  207. package/types/ui/Tab/Menu.d.ts +1 -1
  208. package/types/ui/Table.d.ts +9 -1
  209. package/types/ui/Toast.d.ts +43 -0
  210. package/types/ui/ToggleSelect.d.ts +11 -1
  211. package/types/ui/UiOverride/context.d.ts +3 -0
  212. package/types/ui/Unauthorized.d.ts +3 -1
  213. package/types/ui/index.d.ts +3 -1
  214. package/types/ui/triggerSlot.d.ts +24 -0
  215. package/types/vendor/use-agentic/AgentSession.d.ts +1 -1
  216. package/types/vendor/use-agentic/ToolOutput.d.ts +11 -0
  217. package/types/vendor/use-agentic/ToolRunner.d.ts +70 -0
  218. package/types/vendor/use-agentic/index.d.ts +1 -0
  219. package/types/vendor/use-agentic/types.d.ts +7 -0
  220. package/types/webkit/bootCsr.d.ts +2 -2
  221. package/ui/Agent/Chat.tsx +14 -47
  222. package/ui/Agent/ChatCommands.ts +2 -4
  223. package/ui/Agent/attachment.ts +36 -8
  224. package/ui/Agent/useChatAttachments.ts +17 -8
  225. package/ui/Agent/useChatQueue.ts +6 -4
  226. package/ui/Agent/useSlashMenu.ts +9 -25
  227. package/ui/BottomSheet.tsx +72 -26
  228. package/ui/CsrImage.tsx +2 -2
  229. package/ui/Data/ListContainer.tsx +1 -1
  230. package/ui/Dialog/Modal.tsx +18 -9
  231. package/ui/Dropdown.tsx +21 -12
  232. package/ui/Empty.tsx +4 -2
  233. package/ui/Field/Label.tsx +5 -4
  234. package/ui/Field/Relation.tsx +4 -12
  235. package/ui/Field/index.tsx +2 -2
  236. package/ui/Image.tsx +3 -3
  237. package/ui/InfiniteScroll.tsx +6 -4
  238. package/ui/Layout/BottomTab.tsx +20 -12
  239. package/ui/Layout/LeftSider.tsx +17 -9
  240. package/ui/Layout/RightSider.tsx +18 -14
  241. package/ui/Layout/Sider.tsx +30 -23
  242. package/ui/Load/Units.tsx +14 -3
  243. package/ui/Load/View.tsx +8 -3
  244. package/ui/Loading/Area.tsx +19 -5
  245. package/ui/Menu.tsx +21 -14
  246. package/ui/Modal.tsx +17 -3
  247. package/ui/Model/Edit.tsx +12 -26
  248. package/ui/Model/EditModal.tsx +1 -1
  249. package/ui/Model/New.tsx +12 -21
  250. package/ui/Model/Remove.tsx +39 -16
  251. package/ui/Model/SureToRemove.tsx +45 -30
  252. package/ui/Model/ViewEditModal.tsx +34 -21
  253. package/ui/Pagination.tsx +18 -5
  254. package/ui/Popconfirm.tsx +30 -20
  255. package/ui/Select.tsx +218 -132
  256. package/ui/System/Messages.tsx +76 -122
  257. package/ui/Tab/Menu.tsx +1 -1
  258. package/ui/Table.tsx +16 -2
  259. package/ui/Toast.tsx +132 -0
  260. package/ui/ToggleSelect.tsx +15 -6
  261. package/ui/UiOverride/context.ts +4 -0
  262. package/ui/Unauthorized.tsx +10 -2
  263. package/ui/index.ts +18 -1
  264. package/ui/triggerSlot.tsx +52 -0
  265. package/vendor/use-agentic/AgentSession.ts +22 -92
  266. package/vendor/use-agentic/ToolOutput.ts +24 -0
  267. package/vendor/use-agentic/ToolRunner.ts +174 -0
  268. package/vendor/use-agentic/index.ts +1 -0
  269. package/vendor/use-agentic/types.ts +7 -0
  270. package/webkit/bootCsr.tsx +8 -2
@@ -6,8 +6,10 @@ import type { ConstantModelRef } from "./via";
6
6
  * Which end of a relation goes away with the other. `removeRef` removes what the field points at when this
7
7
  * document is removed; `removeWith` removes this document when what the field points at is removed. The two
8
8
  * read identically on a relation field, so the value has to name the direction — a mistake here is a data loss.
9
+ * `removeWithAny` is `removeWith` over an owner that is unknowable at build time, and it names the whole
10
+ * decision in one value so the widening cannot be declared apart from the direction it widens.
9
11
  */
10
- export const cascadeActions = ["removeRef", "removeWith"] as const;
12
+ export const cascadeActions = ["removeRef", "removeWith", "removeWithAny"] as const;
11
13
  export type CascadeAction = (typeof cascadeActions)[number];
12
14
 
13
15
  /** How a `removeWith` field names the owner whose removal takes this document with it. */
@@ -21,7 +23,7 @@ export interface CascadeWithPath {
21
23
  readonly typeKey: string | null;
22
24
  /** The refNames `typeKey` may hold. Empty unless the field is polymorphic over an enum. */
23
25
  readonly typeValues: readonly string[];
24
- /** Set by `polymorphic: "any"`: `typeKey` is free-form, so the owner is whatever refName the row holds. */
26
+ /** Set by `cascade: "removeWithAny"`: `typeKey` is free-form, so the owner is whatever refName the row holds. */
25
27
  readonly anyOwner: boolean;
26
28
  }
27
29
 
@@ -35,7 +37,6 @@ export class CascadePaths {
35
37
 
36
38
  collect(fieldMap: FieldObject) {
37
39
  for (const [key, field] of Object.entries(fieldMap)) {
38
- this.#assertPolymorphicIsWiredUp(key, field);
39
40
  if (!field.cascade) continue;
40
41
  this.#assertKnownAction(key, field.cascade);
41
42
  if (field.cascade === "removeRef") this.removeRef.set(key, this.#readOwnedRelation(key, field));
@@ -44,16 +45,6 @@ export class CascadePaths {
44
45
  return this;
45
46
  }
46
47
 
47
- /** `polymorphic` widens one thing and nothing else, so anywhere else it is a declaration that does nothing. */
48
- #assertPolymorphicIsWiredUp(key: string, field: ConstantField) {
49
- if (!field.polymorphic) return;
50
- if (field.cascade === "removeWith" && field.refPath) return;
51
- throw new Error(
52
- `Field "${key}" declares polymorphic: "${field.polymorphic}", which only widens a ` +
53
- `cascade: "removeWith" field that names its owner type with refPath`,
54
- );
55
- }
56
-
57
48
  #assertKnownAction(key: string, action: CascadeAction) {
58
49
 
59
50
  if (!cascadeActions.includes(action)) {
@@ -74,7 +65,15 @@ export class CascadePaths {
74
65
 
75
66
  if (field.arrDepth > 0) throw new Error(`Cascade field "${key}" is an array and names more than one owner`);
76
67
  if (field.isMap) throw new Error(`Cascade field "${key}" is a Map and names no owner`);
77
- if (field.refPath) return this.#readPolymorphicOwner(key, field, fieldMap);
68
+ const anyOwner = field.cascade === "removeWithAny";
69
+ if (field.refPath) return this.#readPolymorphicOwner(key, field, fieldMap, anyOwner);
70
+
71
+ if (anyOwner) {
72
+ throw new Error(
73
+ `Cascade field "${key}" declares cascade: "removeWithAny" and must name the field holding the owner's ` +
74
+ `refName with refPath: "<typeField>"`,
75
+ );
76
+ }
78
77
  if (field.ref) {
79
78
  this.#assertHoldsId(key, field);
80
79
  return { key, modelRef: null, refName: field.ref, typeKey: null, typeValues: [], anyOwner: false };
@@ -88,18 +87,18 @@ export class CascadePaths {
88
87
  );
89
88
  }
90
89
 
91
- #readPolymorphicOwner(key: string, field: ConstantField, fieldMap: FieldObject): CascadeWithPath {
90
+ #readPolymorphicOwner(key: string, field: ConstantField, fieldMap: FieldObject, anyOwner: boolean): CascadeWithPath {
92
91
  if (field.ref) throw new Error(`Cascade field "${key}" declares both ref and refPath; keep one`);
93
92
  this.#assertHoldsId(key, field);
94
93
  const typeKey = field.refPath as string;
95
94
  const typeField = fieldMap[typeKey];
96
95
  if (!typeField) throw new Error(`Cascade field "${key}" declares refPath: "${typeKey}", which is not a field`);
97
- if (field.polymorphic === "any") return this.#readAnyOwner(key, typeKey, typeField);
96
+ if (anyOwner) return this.#readAnyOwner(key, typeKey, typeField);
98
97
 
99
98
  if (!typeField.enum) {
100
99
  throw new Error(
101
100
  `Cascade field "${key}" declares refPath: "${typeKey}", which must be an enumOf(...) naming the owner ` +
102
- `refNames it may hold; declare polymorphic: "any" to pay for a sweep on every removal instead`,
101
+ `refNames it may hold; declare cascade: "removeWithAny" to pay for a sweep on every removal instead`,
103
102
  );
104
103
  }
105
104
  const typeValues = typeField.enum.values.map((value) => String(value));
@@ -110,14 +109,15 @@ export class CascadePaths {
110
109
 
111
110
  if (typeField.enum) {
112
111
  throw new Error(
113
- `Cascade field "${key}" declares polymorphic: "any" and a refPath naming an enumOf(...); keep one`,
112
+ `Cascade field "${key}" declares cascade: "removeWithAny" and a refPath naming an enumOf(...), which ` +
113
+ `already names its owners; use cascade: "removeWith"`,
114
114
  );
115
115
  }
116
116
 
117
117
  if (this.#primitiveNameOf(typeField) !== "String") {
118
118
  throw new Error(
119
- `Cascade field "${key}" declares polymorphic: "any", so refPath: "${typeKey}" must be a String field ` +
120
- `holding the owner's refName`,
119
+ `Cascade field "${key}" declares cascade: "removeWithAny", so refPath: "${typeKey}" must be a String ` +
120
+ `field holding the owner's refName`,
121
121
  );
122
122
  }
123
123
  return { key, modelRef: null, refName: null, typeKey, typeValues: [], anyOwner: true };
@@ -1,4 +1,12 @@
1
- import { Any, applyFnToArrayObjects, type Cls, FIELD_META, PrimitiveRegistry, type PrimitiveScalar } from "akanjs/base";
1
+ import {
2
+ Any,
3
+ applyFnToArrayObjects,
4
+ type Cls,
5
+ type EnumInstance,
6
+ FIELD_META,
7
+ PrimitiveRegistry,
8
+ type PrimitiveScalar,
9
+ } from "akanjs/base";
2
10
 
3
11
  import { type ConstantCls, type ConstantModelRef, ConstantRegistry, type FieldProps, withSharedInstances } from ".";
4
12
 
@@ -50,6 +58,7 @@ const deserializeInput = <Input = unknown>(
50
58
  : deserialize(field.modelRef, field.arrDepth, (value as Record<string, unknown>)[key], {
51
59
  key,
52
60
  nullable: field.nullable,
61
+ enum: field.enum,
53
62
  }),
54
63
  ]),
55
64
  ) as unknown as Input;
@@ -57,15 +66,33 @@ const deserializeInput = <Input = unknown>(
57
66
  }
58
67
  };
59
68
 
69
+ interface DeserializeOption {
70
+ key?: string;
71
+ nullable?: boolean;
72
+ convertFn?: (value: unknown) => unknown;
73
+ enum?: EnumInstance;
74
+ }
75
+
76
+ const assertEnumValue = (enumRef: EnumInstance, value: unknown, key?: string): void => {
77
+ if (Array.isArray(value)) {
78
+ for (const item of value) assertEnumValue(enumRef, item, key);
79
+ return;
80
+ }
81
+ if (value === null || value === undefined || enumRef.has(value as never)) return;
82
+ throw new Error(`Invalid Enum Value in ${key}: ${String(value)} is not one of ${enumRef.values.join(", ")}`);
83
+ };
84
+
60
85
  export const deserialize = (
61
86
  argRef: ConstantModelRef | PrimitiveScalar,
62
87
  arrDepth: number,
63
88
  value: unknown,
64
- { key, nullable = false, convertFn }: { key?: string; nullable?: boolean; convertFn?: (value: unknown) => unknown },
89
+ { key, nullable = false, convertFn, enum: enumRef }: DeserializeOption,
65
90
  ) => {
66
91
  if (nullable && (value === null || value === undefined)) return null;
67
92
  else if (!nullable && (value === null || value === undefined) && argRef !== Any)
68
93
  throw new Error(`Invalid Value (Nullable) in ${key} ${argRef} for value ${value}`);
69
94
 
70
- return withSharedInstances(() => deserializeInput(value, argRef, arrDepth, convertFn)) as object[];
95
+ const result = withSharedInstances(() => deserializeInput(value, argRef, arrDepth, convertFn)) as object[];
96
+ if (enumRef) assertEnumValue(enumRef, result, key);
97
+ return result;
71
98
  };
@@ -106,11 +106,6 @@ export interface ConstantFieldProps<
106
106
  validate?: (value: FieldValue, model: any) => boolean;
107
107
  text?: TextFieldRole;
108
108
  cascade?: CascadeAction;
109
- /**
110
- * Widens a `cascade: "removeWith"` field whose `refPath` names a free-form `String` instead of an `enumOf`:
111
- * the owner is whatever refName the row happens to hold, found by sweeping at removal time.
112
- */
113
- polymorphic?: "any";
114
109
  /**
115
110
  * Renders on the page, never reaches an agent. Stripped wherever a value is masked for an AI caller — the
116
111
  * in-page agent's reads and every MCP result — and left untouched everywhere else, so a `File`'s blur
@@ -209,7 +204,6 @@ interface ConstantFieldBuildProps<
209
204
  validate?: (value: FieldValue, model: any) => boolean;
210
205
  text?: TextFieldRole;
211
206
  cascade?: CascadeAction;
212
- polymorphic?: "any";
213
207
  visual: boolean;
214
208
  modelRef: ConstantModelRef;
215
209
  arrDepth: number;
@@ -335,7 +329,6 @@ export class ConstantField<
335
329
  readonly validate?: (value: FieldValue, model: any) => boolean;
336
330
  readonly text?: TextFieldRole;
337
331
  readonly cascade?: CascadeAction;
338
- readonly polymorphic?: "any";
339
332
  readonly visual: boolean;
340
333
  readonly modelRef: ConstantModelRef;
341
334
  readonly arrDepth: number;
@@ -369,7 +362,6 @@ export class ConstantField<
369
362
  this.validate = props.validate;
370
363
  this.text = props.text;
371
364
  this.cascade = props.cascade;
372
- this.polymorphic = props.polymorphic;
373
365
  this.visual = props.visual;
374
366
  this.modelRef = props.modelRef;
375
367
  this.arrDepth = props.arrDepth;
@@ -450,7 +442,6 @@ export class ConstantField<
450
442
  validate: option.validate,
451
443
  text: option.text,
452
444
  cascade: option.cascade,
453
- polymorphic: option.polymorphic,
454
445
  visual: option.visual ?? false,
455
446
  modelRef,
456
447
  arrDepth: arrDepth,
@@ -498,7 +489,6 @@ export class ConstantField<
498
489
  validate: this.validate,
499
490
  text: this.text,
500
491
  cascade: this.cascade,
501
- polymorphic: this.polymorphic,
502
492
  visual: this.visual,
503
493
  modelRef: this.modelRef,
504
494
  arrDepth: this.arrDepth,
@@ -523,19 +513,35 @@ export interface FieldObject {
523
513
  */
524
514
  type WithoutTextRole<Option> = Option extends unknown ? Omit<Option, "text"> : never;
525
515
 
516
+ /**
517
+ * A wildcard owner is read off the row at removal time, so `removeWithAny` without a `refPath` names nothing to
518
+ * read it from — and the price of that action (no cascade in the app removes in one query) is one nobody should
519
+ * pay for a declaration that cascades nothing. Pairing the two in the option type refuses it at the call site;
520
+ * `CascadePaths` keeps the same refusal for the macro and bundled paths that reach it without a typecheck.
521
+ */
522
+ type CascadeOption =
523
+ | { cascade?: "removeRef" | "removeWith"; refPath?: string }
524
+ | { cascade: "removeWithAny"; refPath: string };
525
+
526
+ type WithCascadePair<Option> = Omit<Option, "cascade" | "refPath"> & CascadeOption;
527
+
526
528
  type FieldOption<
527
529
  Value extends ConstantFieldTypeInput,
528
530
  MapValue = Value extends MapConstructor ? typeof PrimitiveScalar : never,
529
531
  Metadata extends { [key: string]: any } = { [key: string]: any },
530
532
  _FieldToValue = FieldToValue<Value, MapValue> | null | undefined,
531
533
  > =
532
- | Omit<
533
- ConstantFieldProps<ConstantFieldKind, _FieldToValue, MapValue, Metadata>,
534
- "enum" | "meta" | "nullable" | "fieldType" | "select"
534
+ | WithCascadePair<
535
+ Omit<
536
+ ConstantFieldProps<ConstantFieldKind, _FieldToValue, MapValue, Metadata>,
537
+ "enum" | "meta" | "nullable" | "fieldType" | "select"
538
+ >
535
539
  >
536
- | Omit<
537
- ConstantFieldProps<ConstantFieldKind, SingleValue<_FieldToValue>, MapValue, Metadata>,
538
- "enum" | "meta" | "nullable" | "fieldType" | "select"
540
+ | WithCascadePair<
541
+ Omit<
542
+ ConstantFieldProps<ConstantFieldKind, SingleValue<_FieldToValue>, MapValue, Metadata>,
543
+ "enum" | "meta" | "nullable" | "fieldType" | "select"
544
+ >
539
545
  >[];
540
546
 
541
547
  export type PlainTypeToFieldType<PlainType> = PlainType extends [infer First, ...infer Rest]
@@ -105,6 +105,8 @@ const purify = (field: FieldProps, key: string, value: unknown, self: Record<str
105
105
  throw new Error(`Invalid Date Value (Default) in ${key} for value ${value}`);
106
106
  if ([String, ID].includes(field.modelRef as unknown as StringConstructor | typeof ID) && (value === "" || !value))
107
107
  throw new Error(`Invalid String Value (Default) in ${key} for value ${value}`);
108
+ if (field.enum && !field.enum.has(value as never))
109
+ throw new Error(`Invalid Enum Value in ${key}: ${String(value)} is not one of ${field.enum.values.join(", ")}`);
108
110
  if (field.validate && !field.validate(value, self))
109
111
  throw new Error(`Invalid Value (Failed to pass validation) / ${value} in ${key}`);
110
112
  if (!field.nullable && !value && value !== 0 && value !== false && (field.modelRef as Cls) !== Any)
package/constant/types.ts CHANGED
@@ -63,18 +63,22 @@ export class BaseInsight {
63
63
  declare count: number;
64
64
  }
65
65
 
66
- export interface ProtoFile {
66
+ export interface ProtoLightFile {
67
67
  id: string;
68
68
  filename: string;
69
69
  abstractData: string | null;
70
70
  imageSize: [number, number];
71
- progress: number | null;
71
+ progress?: number | null;
72
72
  url: string;
73
73
  size: number;
74
74
  status: string;
75
75
  createdAt: Dayjs;
76
76
  updatedAt: Dayjs;
77
77
  removedAt: Dayjs | null;
78
+ }
79
+
80
+ export interface ProtoFile extends ProtoLightFile {
81
+ progress: number | null;
78
82
  mimetype: string;
79
83
  encoding: string;
80
84
  origin: string | null;
@@ -146,6 +146,7 @@ export const baseDictionary = serviceDictionary(["en", "ko"])
146
146
  password: ["Password", "비밀번호"],
147
147
  passwordConfirm: ["Password Confirm", "비밀번호 확인"],
148
148
  noOptions: ["Can't find any datas", "데이터를 찾을 수 없습니다."],
149
+ noSelection: ["No selection", "선택 안 함"],
149
150
  addModel: ["Add {model}", "{model} 추가"],
150
151
  createModel: ["Create {model}", "{model} 생성하기"],
151
152
  createSuccess: ["{model} create success", "{model} 생성 완료"],
@@ -53,6 +53,26 @@ export class DocumentSchema<Doc = unknown> {
53
53
  return this;
54
54
  }
55
55
 
56
+ removePre<HookDoc = Doc>(type: SaveEventType, hook: DocumentSaveHook<HookDoc>) {
57
+ const hooks = this.preHooks.get(type);
58
+ if (hooks)
59
+ this.preHooks.set(
60
+ type,
61
+ hooks.filter((registered) => registered !== (hook as unknown)),
62
+ );
63
+ return this;
64
+ }
65
+
66
+ removePost<HookDoc = Doc>(type: SaveEventType, hook: DocumentSaveHook<HookDoc>) {
67
+ const hooks = this.postHooks.get(type);
68
+ if (hooks)
69
+ this.postHooks.set(
70
+ type,
71
+ hooks.filter((registered) => registered !== (hook as unknown)),
72
+ );
73
+ return this;
74
+ }
75
+
56
76
  hook(type: DocumentHookName, hook: DocumentSaveHook<Doc>) {
57
77
  const [, phase, event] = /^(before|after)(.+)$/.exec(type) ?? [];
58
78
  if (!phase || !event) throw new Error(`Invalid document hook: ${type}`);
@@ -100,6 +100,27 @@ export const fillMissingFilterArgs = (filterInfo: FilterInfo, args: unknown[]) =
100
100
  return [...args, ...Array(filterInfo.args.length - args.length).fill(undefined)];
101
101
  };
102
102
 
103
+ const queryOptionKeys = new Set(["select", "skip", "limit", "sort", "sample"]);
104
+
105
+ const isQueryOptionArg = (value: unknown) => {
106
+ if (!value || typeof value !== "object") return false;
107
+ const proto = Object.getPrototypeOf(value);
108
+ if (proto !== Object.prototype && proto !== null) return false;
109
+ return Object.keys(value).every((key) => queryOptionKeys.has(key));
110
+ };
111
+
112
+ /**
113
+ * Splits a generated filter method's arguments into the filter's own args and the trailing query option.
114
+ * Shared by the database and service resolvers so the two cannot drift into disagreeing about what an option is.
115
+ */
116
+ export const splitFilterArgs = (filterInfo: FilterInfo, args: unknown[]) => {
117
+ const hasQueryOption = args.length > filterInfo.args.length || isQueryOptionArg(args.at(-1));
118
+ return {
119
+ queryArgs: fillMissingFilterArgs(filterInfo, hasQueryOption ? args.slice(0, -1) : args),
120
+ queryOption: (hasQueryOption ? args.at(-1) : {}) as Record<string, unknown>,
121
+ };
122
+ };
123
+
103
124
  export interface FilterArgInfo {
104
125
  name: string;
105
126
  argRef: ConstantFieldType;
package/document/into.ts CHANGED
@@ -24,14 +24,6 @@ interface DefaultMdlStats<
24
24
  pickById: (docId: string | undefined, projection?: _Projection) => Promise<TDocument>;
25
25
  sample: (query: _FilterQuery, size?: number) => Promise<TDocument[]>;
26
26
  sampleOne: (query: _FilterQuery) => Promise<TDocument | null>;
27
- preSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
28
- postSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
29
- preCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
30
- postCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
31
- preUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
32
- postUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
33
- preRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
34
- postRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>>;
35
27
  listenPre: (
36
28
  eventType: SaveEventType,
37
29
  listener: (doc: TDocument, type: CRUDEventType, previous?: TDocument) => PromiseOrObject<void>,
@@ -19,10 +19,16 @@ import type {
19
19
  } from "akanjs/signal";
20
20
  import { agentTurnConstant } from "../agentTurn";
21
21
  import type { ClientSignal, FetchClientType, FetchSignalInput, MergeAllFetchTypes, SliceMeta } from "../fetchType";
22
- import { claimRequestQuery, cookies as requestCookies, headers as requestHeaders } from "../requestStorage";
22
+ import {
23
+ claimRequestQuery,
24
+ recordRequestQuery,
25
+ cookies as requestCookies,
26
+ headers as requestHeaders,
27
+ } from "../requestStorage";
23
28
  import type { GetSliceMetaObjFromDatabaseSignals } from "../types";
24
29
  import { FetchHandle } from "./fetchHandle";
25
- import { type ErrorConstructor, HttpClient } from "./httpClient";
30
+ import { HttpClient } from "./httpClient";
31
+ import type { ErrorConstructor } from "./remoteError";
26
32
  import { SliceInitHandle } from "./sliceInitHandle";
27
33
  import { WsClient } from "./wsClient";
28
34
 
@@ -302,8 +308,6 @@ export class FetchClient {
302
308
  const parseReturn = this.#makeReturnParser(endpoint.returns);
303
309
  const { bodyArgs, uploadArgs } = FetchClient.classifyHttpArgs(endpoint.args);
304
310
  switch (endpoint.type) {
305
-
306
- case "prompt":
307
311
  case "query": {
308
312
  const queryFn = async (...argData: unknown[]) => {
309
313
  const args = argData.slice(0, argLength);
@@ -318,6 +322,7 @@ export class FetchClient {
318
322
  const claim = baseUrl
319
323
  ? { value: requestQuery(), owned: true }
320
324
  : claimRequestQuery(FetchClient.#makeRequestQueryCacheKey(this.origin, url, headers), requestQuery);
325
+ recordRequestQuery({ key, args: Object.fromEntries(argMap), returns: endpoint.returns, value: claim.value });
321
326
  const response = await claim.value;
322
327
  const payload = claim.owned ? response : FetchClient.#deepCopy(response);
323
328
  return parseReturn(payload, { crystalize: option?.crystalize ?? true });
@@ -346,7 +351,6 @@ export class FetchClient {
346
351
  }
347
352
  #registerEndpoint(key: string, endpoint: SerializedEndpoint, prefix?: string) {
348
353
  switch (endpoint.type) {
349
- case "prompt":
350
354
  case "query": {
351
355
  this.#setHandlerFactory(key, () => this.#makeHttpFn(key, endpoint, prefix));
352
356
  return;
@@ -455,8 +459,10 @@ export class FetchClient {
455
459
  const updateGuards = signal.updateGuards ?? signal.cruGuards;
456
460
  const removeGuards = signal.removeGuards ?? signal.cruGuards;
457
461
 
458
- const mcp = (verb: keyof NonNullable<SerializedSignal["mcp"]>) =>
459
- signal.mcp?.[verb] === false ? { mcp: false as const } : {};
462
+ const mcp = (verb: keyof NonNullable<SerializedSignal["mcp"]>) => ({
463
+ ...(signal.mcp?.[verb] === false ? { mcp: false as const } : {}),
464
+ ...(signal.agents?.[verb] === false ? { agents: false as const } : {}),
465
+ });
460
466
  const endpoint: { [key: string]: SerializedEndpoint } = {};
461
467
  if (signal.getGuards) {
462
468
  endpoint[names.model] = {
@@ -630,7 +636,10 @@ export class FetchClient {
630
636
  live: `${refName}Live${capSuffix}`,
631
637
  };
632
638
 
633
- const mcp = slice.mcp === false ? { mcp: false as const } : {};
639
+ const mcp = {
640
+ ...(slice.mcp === false ? { mcp: false as const } : {}),
641
+ ...(slice.agents === false ? { agents: false as const } : {}),
642
+ };
634
643
  const endpoint: { [key: string]: SerializedEndpoint } = {
635
644
  [names.list]: {
636
645
  type: "query",
@@ -1,26 +1,5 @@
1
1
  import type { HttpMutationMethod, SerializedArg } from "akanjs/signal";
2
-
3
- export interface ErrorResponsePayload {
4
- error: string;
5
- statusCode?: number;
6
- data?: Record<string, unknown>;
7
- details?: unknown;
8
- path?: string;
9
- timestamp?: string;
10
- }
11
-
12
- export interface RestoredError extends Error {
13
- error?: string;
14
- statusCode?: number;
15
- data?: unknown;
16
- details?: unknown;
17
- path?: string;
18
- timestamp?: string;
19
- }
20
-
21
- export interface ErrorConstructor {
22
- fromJSON: (payload: ErrorResponsePayload) => RestoredError;
23
- }
2
+ import { type ErrorConstructor, type RestoredError, restoreRemoteError } from "./remoteError";
24
3
 
25
4
  export interface HttpClientOptions {
26
5
  headers?: Record<string, string>;
@@ -199,14 +178,7 @@ export class HttpClient {
199
178
  }
200
179
 
201
180
  #restoreError(body: unknown, fallbackStatusCode: number): RestoredError {
202
- const payload =
203
- body && typeof body === "object" && "error" in body
204
- ? ({ statusCode: fallbackStatusCode, ...(body as Record<string, unknown>) } as ErrorResponsePayload)
205
- : ({ error: String(body), statusCode: fallbackStatusCode } satisfies ErrorResponsePayload);
206
- if (this.ErrorCls) return this.ErrorCls.fromJSON(payload);
207
- const error = new Error(payload.error);
208
- Object.assign(error, payload);
209
- return error;
181
+ return restoreRemoteError(body, fallbackStatusCode, this.ErrorCls);
210
182
  }
211
183
  static makePath(key: string, paramArgs: SerializedArg[], prefix?: string) {
212
184
  const paramPath = paramArgs.length > 0 ? `/${paramArgs.map((arg) => `:${arg.name}`).join("/")}` : "";
@@ -1,3 +1,4 @@
1
1
  export * from "./fetchClient";
2
2
  export * from "./httpClient";
3
+ export * from "./remoteError";
3
4
  export * from "./wsClient";
@@ -0,0 +1,57 @@
1
+ export interface ErrorResponsePayload {
2
+ error: string;
3
+ statusCode?: number;
4
+ data?: Record<string, unknown>;
5
+ details?: unknown;
6
+ path?: string;
7
+ timestamp?: string;
8
+ }
9
+
10
+ export interface RestoredError extends Error {
11
+ error?: string;
12
+ statusCode?: number;
13
+ data?: unknown;
14
+ details?: unknown;
15
+ path?: string;
16
+ timestamp?: string;
17
+ toJSON?: () => ErrorResponsePayload;
18
+ }
19
+
20
+ export interface ErrorConstructor {
21
+ fromJSON: (payload: ErrorResponsePayload) => RestoredError;
22
+ }
23
+
24
+ /**
25
+ * Rebuilds what a remote process reported: the caller's own `Err` when this client was given one, and a
26
+ * duck-typed `Error` carrying the same payload otherwise.
27
+ *
28
+ * The `toJSON` is what makes the second case rethrowable. A server process that calls another with `{ origin }`
29
+ * and lets the failure propagate is answered by `SignalContext.try`, which forwards a payload only when the
30
+ * thrown value carries both `statusCode` and `toJSON`; anything else is this repo's own bug and is generalized
31
+ * to `Internal Server Error`. Without it the hop loses the dictionary key and its data, and the browser toasts
32
+ * the generalization instead of the sentence the remote endpoint chose.
33
+ */
34
+ export const restoreRemoteError = (
35
+ body: unknown,
36
+ fallbackStatusCode: number,
37
+ ErrorCls?: ErrorConstructor,
38
+ ): RestoredError => {
39
+ const payload =
40
+ body && typeof body === "object" && "error" in body
41
+ ? ({ statusCode: fallbackStatusCode, ...(body as Record<string, unknown>) } as ErrorResponsePayload)
42
+ : ({ error: String(body), statusCode: fallbackStatusCode } satisfies ErrorResponsePayload);
43
+ if (ErrorCls) return ErrorCls.fromJSON(payload);
44
+ const error = new Error(payload.error) as RestoredError;
45
+ Object.assign(error, payload);
46
+
47
+ const json: ErrorResponsePayload = {
48
+ error: payload.error,
49
+ statusCode: payload.statusCode ?? fallbackStatusCode,
50
+ ...(payload.details !== undefined ? { details: payload.details } : {}),
51
+ ...(payload.data !== undefined ? { data: payload.data } : {}),
52
+ ...(payload.path !== undefined ? { path: payload.path } : {}),
53
+ ...(payload.timestamp !== undefined ? { timestamp: payload.timestamp } : {}),
54
+ };
55
+ error.toJSON = () => json;
56
+ return error;
57
+ };
@@ -7,7 +7,7 @@ import type {
7
7
  WebsocketResData,
8
8
  WebsocketSubscribeAck,
9
9
  } from "akanjs/signal";
10
- import type { ErrorConstructor, ErrorResponsePayload, RestoredError } from "./httpClient";
10
+ import { type ErrorConstructor, type RestoredError, restoreRemoteError } from "./remoteError";
11
11
 
12
12
  export interface WsClientReconnectOptions {
13
13
  enabled?: boolean;
@@ -216,14 +216,7 @@ export class WsClient {
216
216
  }
217
217
 
218
218
  #restoreError(body: unknown): RestoredError {
219
- const payload =
220
- body && typeof body === "object" && "error" in body
221
- ? (body as ErrorResponsePayload)
222
- : ({ error: String(body), statusCode: 500 } satisfies ErrorResponsePayload);
223
- if (this.ErrorCls) return this.ErrorCls.fromJSON(payload);
224
- const error = new Error(payload.error);
225
- Object.assign(error, payload);
226
- return error;
219
+ return restoreRemoteError(body, 500, this.ErrorCls);
227
220
  }
228
221
 
229
222
  destroy() {
@@ -12,11 +12,20 @@ export interface AkanDynamicUsage {
12
12
  cookies: boolean;
13
13
  }
14
14
 
15
+ /** One `fetch.*` query a request made, by endpoint and argument — what a page's data footprint is read off. */
16
+ export interface RequestQueryRecord {
17
+ key: string;
18
+ args: Record<string, unknown>;
19
+ returns: { refName: string; modelType?: string; arrDepth?: number; nullable?: boolean };
20
+ value: Promise<unknown>;
21
+ }
22
+
15
23
  export interface AkanRequestStore {
16
24
  request: Request;
17
25
  theme?: AkanTheme;
18
26
  frameState?: unknown;
19
27
  queryCache: Map<string, Promise<unknown>>;
28
+ queryLog: RequestQueryRecord[];
20
29
  policy: AkanRequestPolicy;
21
30
  dynamicUsage: AkanDynamicUsage;
22
31
  }
@@ -62,6 +71,7 @@ export function createRequestStore(
62
71
  return {
63
72
  request,
64
73
  queryCache: new Map(),
74
+ queryLog: [],
65
75
  policy: { ...createRequestPolicy(), ...policy },
66
76
  dynamicUsage: { headers: false, cookies: false },
67
77
  };
@@ -189,6 +199,11 @@ export function claimRequestQuery<T>(key: string, factory: () => Promise<T>): {
189
199
  return { value: promise, owned: true };
190
200
  }
191
201
 
202
+ /** Appends to the active request's query log; outside a request there is nothing to read it, so nothing is kept. */
203
+ export function recordRequestQuery(record: RequestQueryRecord): void {
204
+ getRequestStore()?.queryLog.push(record);
205
+ }
206
+
192
207
  /** Deduplicates a promise-producing query within the active request. */
193
208
  export function memoizeRequestQuery<T>(key: string, factory: () => Promise<T>): Promise<T> {
194
209
  return claimRequestQuery(key, factory).value;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akanjs",
3
- "version": "3.0.0-alpha.99",
3
+ "version": "3.0.0-beta.0",
4
4
  "sourceType": "module",
5
5
  "type": "module",
6
6
  "publishConfig": {