cabloy 5.1.58 → 5.1.60

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 (112) hide show
  1. package/.claude/skills/cabloy-contract-loop/SKILL.md +16 -0
  2. package/.claude/skills/cabloy-contract-loop/references/contract-loop-map.md +26 -0
  3. package/.claude/skills/cabloy-contract-loop/references/resource-custom-state-pattern.md +144 -0
  4. package/.claude/skills/cabloy-contract-loop/references/verification-checklist.md +18 -0
  5. package/.claude/skills/cabloy-resource-field-update/SKILL.md +267 -0
  6. package/.claude/skills/cabloy-resource-field-update/evals/evals.json +53 -0
  7. package/.claude/skills/cabloy-resource-field-update/references/custom-renderer-demo-checklist.md +102 -0
  8. package/.claude/skills/cabloy-resource-field-update/references/field-update-decision-tree.md +120 -0
  9. package/.claude/skills/cabloy-resource-field-update/references/follow-up-checklist.md +80 -0
  10. package/.claude/skills/cabloy-resource-field-update/references/verification-checklist.md +97 -0
  11. package/.github/workflows/docs-pages.yml +2 -0
  12. package/.github/workflows/vona-cov-pg.yml +2 -0
  13. package/.github/workflows/vona-test-crud.yml +4 -2
  14. package/.github/workflows/vona-test-mysql.yml +2 -0
  15. package/.github/workflows/vona-test-pg.yml +2 -0
  16. package/.github/workflows/vona-test-sqlite3.yml +2 -0
  17. package/.github/workflows/vona-tsc.yml +2 -0
  18. package/.github/workflows/zova-ui.yml +2 -0
  19. package/.gitignore +0 -4
  20. package/CHANGELOG.md +41 -0
  21. package/CLAUDE.md +2 -0
  22. package/README.md +15 -0
  23. package/cabloy-docs/.vitepress/config.mjs +43 -0
  24. package/cabloy-docs/ai/class-placement-rule.md +2 -0
  25. package/cabloy-docs/ai/cli-to-skill-map.md +7 -0
  26. package/cabloy-docs/ai/future-skill-roadmap.md +17 -2
  27. package/cabloy-docs/backend/bean-scene-authoring.md +350 -0
  28. package/cabloy-docs/backend/cli.md +26 -1
  29. package/cabloy-docs/backend/foundation.md +28 -3
  30. package/cabloy-docs/backend/introduction.md +8 -0
  31. package/cabloy-docs/backend/service-guide.md +2 -0
  32. package/cabloy-docs/backend/websocket-call-flow.md +435 -0
  33. package/cabloy-docs/backend/websocket-guide.md +455 -0
  34. package/cabloy-docs/backend/websocket-protocol-guide.md +381 -0
  35. package/cabloy-docs/backend/websocket-usage-guide.md +356 -0
  36. package/cabloy-docs/frontend/bean-scene-authoring.md +372 -0
  37. package/cabloy-docs/frontend/behavior-guide.md +449 -0
  38. package/cabloy-docs/frontend/cli.md +12 -0
  39. package/cabloy-docs/frontend/introduction.md +5 -0
  40. package/cabloy-docs/frontend/ioc-and-beans.md +10 -9
  41. package/cabloy-docs/frontend/router-tabs-admin-web-comparison.md +206 -0
  42. package/cabloy-docs/frontend/router-tabs-introduction.md +106 -0
  43. package/cabloy-docs/frontend/router-tabs-mechanism.md +469 -0
  44. package/cabloy-docs/frontend/router-tabs-overview.md +227 -0
  45. package/cabloy-docs/frontend/router-tabs-route-meta-cookbook.md +343 -0
  46. package/cabloy-docs/frontend/ssr-architecture-overview.md +211 -0
  47. package/cabloy-docs/frontend/ssr-build-deploy-guide.md +308 -0
  48. package/cabloy-docs/frontend/ssr-review-checklist.md +184 -0
  49. package/cabloy-docs/frontend/ssr-troubleshooting-guide.md +301 -0
  50. package/cabloy-docs/fullstack/framework-performance.md +3 -3
  51. package/cabloy-docs/fullstack/introduction.md +29 -0
  52. package/cabloy-docs/fullstack/quickstart.md +7 -1
  53. package/cabloy-docs/fullstack/tutorial-1-first-module.md +111 -0
  54. package/cabloy-docs/fullstack/tutorial-2-first-crud.md +122 -0
  55. package/cabloy-docs/fullstack/tutorial-3-frontend-metadata-sharing.md +131 -0
  56. package/cabloy-docs/fullstack/tutorial-4-custom-level-renderers.md +119 -0
  57. package/cabloy-docs/fullstack/tutorial-5-backend-contract-sharing.md +144 -0
  58. package/cabloy-docs/fullstack/tutorial-6-one-contract-four-uses.md +168 -0
  59. package/cabloy-docs/fullstack/tutorials-overview.md +179 -0
  60. package/cabloy-docs/index.md +4 -3
  61. package/cabloy-docs/reference/bean-scene-boilerplates.md +73 -0
  62. package/cabloy-docs/reference/cli-reference.md +2 -0
  63. package/package.json +6 -2
  64. package/scripts/init.ts +18 -2
  65. package/scripts/upgrade.ts +6 -0
  66. package/vona/packages-cli/cabloy-cli/package.json +2 -2
  67. package/vona/packages-cli/cli/package.json +1 -1
  68. package/vona/packages-cli/cli-set-api/package.json +1 -1
  69. package/vona/packages-cli/cli-set-api/src/lib/bean/cli.create.module.ts +4 -0
  70. package/vona/packages-utils/zod-query/package.json +1 -1
  71. package/vona/packages-vona/vona/package.json +1 -1
  72. package/vona/packages-vona/vona-core/package.json +1 -1
  73. package/vona/packages-vona/vona-mock/package.json +1 -1
  74. package/vona/pnpm-lock.yaml +133 -1088
  75. package/vona/pnpm-workspace.yaml +0 -1
  76. package/vona/src/suite-vendor/a-vona/modules/a-core/assets/static/img/vona.svg +1 -1
  77. package/vona/src/suite-vendor/a-vona/modules/a-core/package.json +1 -1
  78. package/vona/src/suite-vendor/a-vona/modules/a-openapi/package.json +1 -1
  79. package/vona/src/suite-vendor/a-vona/modules/a-openapiutils/package.json +1 -1
  80. package/vona/src/suite-vendor/a-vona/modules/a-permission/package.json +1 -1
  81. package/vona/src/suite-vendor/a-vona/modules/a-permission/src/bean/bean.permission.ts +1 -1
  82. package/vona/src/suite-vendor/a-vona/modules/a-upload/package.json +2 -2
  83. package/vona/src/suite-vendor/a-vona/modules/a-web/package.json +1 -1
  84. package/vona/src/suite-vendor/a-vona/package.json +1 -1
  85. package/zova/package.original.json +1 -1
  86. package/zova/packages-cli/cli/package.json +3 -3
  87. package/zova/packages-cli/cli-set-front/cli/templates/init/icon/boilerplate/icons/default/zova.svg +1 -1
  88. package/zova/packages-cli/cli-set-front/package.json +3 -3
  89. package/zova/packages-cli/cli-set-front/src/lib/bean/cli.create.module.ts +4 -0
  90. package/zova/packages-cli/cli-set-front/src/lib/command/create.bean.ts +5 -1
  91. package/zova/packages-utils/zova-jsx/package.json +2 -2
  92. package/zova/packages-utils/zova-vite/package.json +2 -2
  93. package/zova/packages-zova/zova/package.json +3 -3
  94. package/zova/packages-zova/zova-core/package.json +2 -2
  95. package/zova/pnpm-lock.yaml +284 -1313
  96. package/zova/pnpm-workspace.yaml +0 -1
  97. package/zova/src/suite/a-home/modules/home-icon/icons/social/cabloy.svg +1 -1
  98. package/zova/src/suite/a-home/modules/home-icon/icons/social/vona.svg +1 -1
  99. package/zova/src/suite/a-home/modules/home-icon/icons/social/zova.svg +1 -1
  100. package/zova/src/suite/a-home/modules/home-icon/src/.metadata/icons/groups/social.svg +3 -3
  101. package/zova/src/suite/cabloy-basic/modules/basic-select/src/component/formFieldSelect/controller.tsx +9 -0
  102. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  103. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +66 -16
  104. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
  105. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/package.json +1 -1
  106. package/zova/src/suite-vendor/a-zova/modules/a-routertabs/src/model/tabs.ts +60 -18
  107. package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableActionRow/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  108. package/zova/src/suite-vendor/a-zova/modules/a-table/cli/tableCell/boilerplate/{{sceneName}}.{{beanName}}.tsx_ +6 -1
  109. package/zova/src/suite-vendor/a-zova/modules/a-table/package.json +1 -1
  110. package/zova/src/suite-vendor/a-zova/modules/a-zod/package.json +2 -2
  111. package/zova/src/suite-vendor/a-zova/modules/a-zova/package.json +3 -3
  112. package/zova/src/suite-vendor/a-zova/package.json +5 -5
@@ -0,0 +1,381 @@
1
+ # Web Socket Protocol Guide
2
+
3
+ This guide explains the built-in wire protocol used by `a-socket` in Vona within the Cabloy monorepo.
4
+
5
+ Read this together with:
6
+
7
+ - [Web Socket Guide](/backend/websocket-guide)
8
+ - [Web Socket Usage Guide](/backend/websocket-usage-guide)
9
+ - [Web Socket Call Flow](/backend/websocket-call-flow)
10
+
11
+ ## Why this protocol guide exists
12
+
13
+ The architecture guide explains how the Web Socket runtime is structured, and the usage guide explains how backend modules should use it.
14
+
15
+ This page answers a narrower question:
16
+
17
+ - what bytes and payload shapes travel over the socket when the built-in protocol is used?
18
+
19
+ That matters when you are:
20
+
21
+ - writing a browser or non-browser client against the current server contract
22
+ - debugging why one side cannot parse an event
23
+ - understanding the `sysReady`, `sysPerformAction`, and `sysPerformActionBack` system events
24
+ - tracing how `ws.sendEvent(...)` encodes outbound data and how packet decoding restores it on inbound traffic
25
+
26
+ ## Source-truth files
27
+
28
+ The protocol contract is grounded in these files:
29
+
30
+ - `vona/src/suite-vendor/a-cabloy/modules/a-socket/src/types/socketEvent.ts`
31
+ - `vona/src/suite-vendor/a-cabloy/modules/a-socket/src/config/config.ts`
32
+ - `vona/src/suite-vendor/a-cabloy/modules/a-socket/src/bean/socketConnection.event.ts`
33
+ - `vona/src/suite-vendor/a-cabloy/modules/a-socket/src/bean/socketPacket.event.ts`
34
+ - `vona/src/suite-vendor/a-cabloy/modules/a-socket/src/bean/socketPacket.performAction.ts`
35
+
36
+ If this guide and source ever disagree, prefer the current source.
37
+
38
+ ## The event transport model
39
+
40
+ The built-in protocol wraps event messages as:
41
+
42
+ - a string prefix
43
+ - followed by JSON
44
+
45
+ The default prefix is:
46
+
47
+ - `'_:'`
48
+
49
+ The JSON body is serialized as a two-element array:
50
+
51
+ - `[eventNameOrShortCode, data]`
52
+
53
+ So the wire model is:
54
+
55
+ ```text
56
+ _:[eventNameOrShortCode, data]
57
+ ```
58
+
59
+ More precisely, the server sends:
60
+
61
+ ```typescript
62
+ `${eventPrefix}${JSON.stringify([eventNameInner, data])}`
63
+ ```
64
+
65
+ That means the Web Socket protocol is event-oriented rather than frame-schema-oriented.
66
+
67
+ ## Prefix behavior
68
+
69
+ The event prefix comes from module config:
70
+
71
+ ```typescript
72
+ return {
73
+ eventPrefix: '_:',
74
+ }
75
+ ```
76
+
77
+ A practical interpretation is:
78
+
79
+ - if an inbound string begins with `'_:'`, `a-socket` treats it as an event packet
80
+ - if it does not begin with `'_:'`, the built-in event decoder forwards it as ordinary raw data
81
+
82
+ This is why the prefix is the first protocol boundary.
83
+
84
+ ## Outbound event encoding
85
+
86
+ The outbound helper is attached during the connection onion `event` stage through:
87
+
88
+ - `ws.sendEvent(...)`
89
+
90
+ Its behavior is:
91
+
92
+ 1. take `eventName` and `data`
93
+ 2. map the event name to a short code if one exists in `socketEventRecord`
94
+ 3. serialize `[mappedName, data]` with `JSON.stringify(...)`
95
+ 4. prepend the `eventPrefix`
96
+ 5. send the final string with `ws.send(...)`
97
+
98
+ Representative shape:
99
+
100
+ ```typescript
101
+ const eventNameInner = socketEventRecord[eventName] ?? eventName;
102
+ ws.send(`${this.scope.config.eventPrefix}${JSON.stringify([eventNameInner, data])}`);
103
+ ```
104
+
105
+ This means custom namespace events usually travel with their original event names, while built-in system events may travel with compact short codes.
106
+
107
+ ## Inbound event decoding
108
+
109
+ Inbound decoding happens in `socketPacket.event.ts`.
110
+
111
+ Its behavior is:
112
+
113
+ 1. check whether the raw payload is a string
114
+ 2. check whether the string starts with the configured event prefix
115
+ 3. remove the prefix
116
+ 4. parse the remaining JSON
117
+ 5. reverse-map built-in short codes through `socketEventRecordReverse`
118
+ 6. forward a normalized packet `[eventName, data]`
119
+
120
+ If the raw payload is not an event-formatted string, the decoder forwards:
121
+
122
+ - `[undefined, rawData]`
123
+
124
+ A practical interpretation is:
125
+
126
+ - event packets become normalized `(eventName, data)` packets
127
+ - non-event packets remain possible, but they do not participate in the built-in event-name protocol unless another packet handler interprets them
128
+
129
+ ## Built-in system event names and short codes
130
+
131
+ The built-in system event mapping is:
132
+
133
+ - `sysReady -> _a`
134
+ - `sysPerformAction -> _b`
135
+ - `sysPerformActionBack -> _c`
136
+
137
+ Reverse mapping is:
138
+
139
+ - `_a -> sysReady`
140
+ - `_b -> sysPerformAction`
141
+ - `_c -> sysPerformActionBack`
142
+
143
+ A useful rule is:
144
+
145
+ - use the human-readable names when discussing the protocol logically
146
+ - expect the short forms on the wire for those built-in events
147
+
148
+ ## Protocol frame examples
149
+
150
+ ### Example 1: server ready signal
151
+
152
+ Logical event:
153
+
154
+ ```text
155
+ sysReady
156
+ ```
157
+
158
+ Wire packet:
159
+
160
+ ```text
161
+ _: ["_a",null]
162
+ ```
163
+
164
+ Because `sysReady` has payload type `never`, the built-in sender still serializes the packet as a two-slot array, so the second slot is `null` in the JSON wire form shown here.
165
+
166
+ The important contract point is:
167
+
168
+ - the first slot is `_a`
169
+ - the packet means the server-side connection setup completed
170
+
171
+ ### Example 2: custom namespace event
172
+
173
+ Suppose a namespace event name is:
174
+
175
+ - `messageCreated`
176
+
177
+ and the payload is:
178
+
179
+ ```json
180
+ { "roomId": "r1", "messageId": "m8", "text": "hello" }
181
+ ```
182
+
183
+ Then a representative wire packet is:
184
+
185
+ ```text
186
+ _:["messageCreated",{"roomId":"r1","messageId":"m8","text":"hello"}]
187
+ ```
188
+
189
+ Because this is not one of the built-in short-coded system events, the event name stays as `messageCreated`.
190
+
191
+ ### Example 3: perform-action request
192
+
193
+ Logical event name:
194
+
195
+ - `sysPerformAction`
196
+
197
+ Representative logical payload:
198
+
199
+ ```json
200
+ {
201
+ "i": 1,
202
+ "m": "get",
203
+ "p": "/demo/student/findOne",
204
+ "q": { "id": 3 },
205
+ "h": { "x-demo": "1" }
206
+ }
207
+ ```
208
+
209
+ Representative wire packet:
210
+
211
+ ```text
212
+ _:["_b",{"i":1,"m":"get","p":"/demo/student/findOne","q":{"id":3},"h":{"x-demo":"1"}}]
213
+ ```
214
+
215
+ ## `sysReady`
216
+
217
+ `sysReady` is the built-in server-ready handshake event.
218
+
219
+ It is sent by the server after:
220
+
221
+ - the socket was accepted
222
+ - the connection onion `enter` chain completed successfully
223
+ - handlers for close, message, and error were installed
224
+
225
+ A client can interpret `sysReady` as:
226
+
227
+ - the connection is alive at the protocol level
228
+ - the backend-side startup for this socket completed
229
+ - request-like packet traffic can begin
230
+
231
+ ## `sysPerformAction`
232
+
233
+ `sysPerformAction` is the built-in request-like event for invoking backend actions over Web Socket.
234
+
235
+ Its inner payload shape is:
236
+
237
+ ```typescript
238
+ interface ISocketEventPerformActionOptionsInner {
239
+ i: number;
240
+ m: 'get' | 'post' | 'delete' | 'put' | 'patch';
241
+ q?: object;
242
+ p: string;
243
+ b?: any;
244
+ h?: object;
245
+ }
246
+ ```
247
+
248
+ Field meanings:
249
+
250
+ - `i` -> request id chosen by the client
251
+ - `m` -> method
252
+ - `p` -> backend path
253
+ - `q` -> query object
254
+ - `b` -> body
255
+ - `h` -> headers object
256
+
257
+ A practical interpretation is:
258
+
259
+ - this is a compact RPC-like request envelope
260
+ - it reuses the backend action execution path rather than inventing a second business-dispatch model
261
+
262
+ ## `sysPerformActionBack`
263
+
264
+ `sysPerformActionBack` is the reply event for `sysPerformAction`.
265
+
266
+ On success, the built-in server handler sends:
267
+
268
+ ```json
269
+ { "i": 1, "c": 0, "d": <result> }
270
+ ```
271
+
272
+ On failure, it sends:
273
+
274
+ ```json
275
+ { "i": 1, "c": <errorCode>, "m": "error message" }
276
+ ```
277
+
278
+ Field meanings in practice:
279
+
280
+ - `i` -> matches the original request id
281
+ - `c` -> status code, with `0` meaning success
282
+ - `d` -> result data on success
283
+ - `m` -> error message on failure
284
+
285
+ A client should therefore match replies to requests by `i`.
286
+
287
+ ## Request-response pairing model
288
+
289
+ The built-in protocol does not create a separate reply channel name per action.
290
+
291
+ Instead, the pairing model is:
292
+
293
+ 1. client sends one `sysPerformAction` packet with request id `i`
294
+ 2. server executes the action
295
+ 3. server sends one `sysPerformActionBack` packet with the same `i`
296
+ 4. client resolves or rejects the in-flight request by matching that id
297
+
298
+ That means the request id is the essential correlation field.
299
+
300
+ ## Custom event naming model
301
+
302
+ For application-defined namespace events, a practical rule is:
303
+
304
+ - choose stable event names such as `messageCreated`, `typing`, `reload`, or `orderCreated`
305
+ - keep the namespace path for channel identity
306
+ - keep the event name for action identity
307
+ - keep the payload object for data
308
+
309
+ This keeps the protocol understandable on both sides.
310
+
311
+ A useful split is:
312
+
313
+ - namespace path -> which channel
314
+ - event name -> which signal
315
+ - payload -> which data
316
+
317
+ ## JSON compatibility considerations
318
+
319
+ Because the built-in protocol uses `JSON.stringify(...)`, payloads should stay JSON-friendly.
320
+
321
+ Prefer payloads such as:
322
+
323
+ - objects
324
+ - arrays
325
+ - strings
326
+ - numbers
327
+ - booleans
328
+ - null
329
+
330
+ Be careful with values such as:
331
+
332
+ - functions
333
+ - class instances that rely on prototype behavior
334
+ - circular objects
335
+ - non-JSON-native runtime values
336
+
337
+ A practical rule is:
338
+
339
+ - if you would not confidently send it through ordinary JSON serialization, do not assume it is a good socket event payload either
340
+
341
+ ## Relationship to non-event packets
342
+
343
+ The built-in decoder only interprets the event protocol when:
344
+
345
+ - the inbound data is a string
346
+ - and the string starts with the configured event prefix
347
+
348
+ Otherwise the packet is forwarded as raw data through `[undefined, rawData]`.
349
+
350
+ This means:
351
+
352
+ - the built-in event protocol is the normal and preferred path
353
+ - custom packet behavior can still exist through additional `socketPacket` handlers
354
+ - but if you want interoperability with the built-in helpers, stay inside the prefixed JSON event format
355
+
356
+ ## Practical client checklist
357
+
358
+ When implementing a client against the current server contract, ask:
359
+
360
+ 1. does the connection URL use the correct `/ws/...` namespace path?
361
+ 2. does the client wait for `sysReady` before assuming the socket is ready?
362
+ 3. are outbound event packets prefixed with `'_:'`?
363
+ 4. are built-in system event short codes handled correctly?
364
+ 5. if using `sysPerformAction`, does each request carry a unique `i` and does the reply matcher use the same field?
365
+
366
+ If those answers are correct, the client-side protocol integration will usually align with the current `a-socket` implementation.
367
+
368
+ ## Related guides
369
+
370
+ Read this page together with:
371
+
372
+ - [Web Socket Guide](/backend/websocket-guide)
373
+ - [Web Socket Usage Guide](/backend/websocket-usage-guide)
374
+ - [Web Socket Call Flow](/backend/websocket-call-flow)
375
+
376
+ Use the practical split:
377
+
378
+ - [Web Socket Guide](/backend/websocket-guide) for architecture
379
+ - [Web Socket Usage Guide](/backend/websocket-usage-guide) for server-side authoring patterns
380
+ - [Web Socket Call Flow](/backend/websocket-call-flow) for source tracing
381
+ - this page for client-visible wire format and built-in protocol fields