@luckystack/sync 0.1.9 → 0.2.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.
@@ -115,21 +115,22 @@ Project codes can carry whatever slots their templates declare. The normalizer d
115
115
 
116
116
  Fired whenever a rate-limit bucket rejects a sync request. The payload differs by `scope`:
117
117
 
118
- ### Scope `'user'` or `'route'` (per-route bucket, identified by token or by IP)
118
+ ### Scope `'user'` or `'ip'` (per-route bucket, identified by token or by IP)
119
119
 
120
120
  ```ts
121
121
  {
122
- scope: 'user' | 'route',
122
+ scope: 'user' | 'ip',
123
123
  key: string, // 'token:<token>:sync:<routeName>' or 'ip:<ip>:sync:<routeName>'
124
124
  limit: number, // projectConfig.rateLimiting.defaultApiLimit
125
125
  windowMs: number, // projectConfig.rateLimiting.windowMs
126
126
  count: number, // limit + 1 (the request that tipped over)
127
- route: string, // e.g. 'board/moveCard/v1'
127
+ route: string, // e.g. 'board/moveCard/v1' — marks this a per-route bucket
128
128
  userId: string | undefined,
129
+ ip: string | undefined, // set when anonymous (no token), else undefined
129
130
  }
130
131
  ```
131
132
 
132
- `scope: 'user'` when the request carried a session token; `scope: 'route'` when it was anonymous (only an IP).
133
+ `scope: 'user'` when the request carried a session token; `scope: 'ip'` when it was anonymous (the per-route bucket is then IP-keyed). The `route` field stays set in both cases to distinguish this per-route bucket from the global `:sync:all` IP bucket below (parity with the API handler).
133
134
 
134
135
  ### Scope `'ip'` (global per-IP bucket, across all sync routes)
135
136
 
@@ -54,6 +54,8 @@ Key rules:
54
54
  - **`auth: AuthProps` is mandatory.** Drives the framework's auth gate (`auth.login` -> require session, `auth.additional` -> run `validateRequest` predicates). See `@luckystack/login` `AuthProps`.
55
55
  - **Return must include `status: 'success' | 'error'`.** Anything else collapses to `sync.invalidServerResponse`. The rest of the object is forwarded as `serverOutput` (after stripping `status`).
56
56
  - **Streaming primitives are received as params.** See [`./streaming.md`](./streaming.md) for the audience matrix.
57
+ - **Optional `export const validation`** toggles runtime input validation, exactly like the API handler. `'strict'` (default, or omit the export) validates `clientInput` against the generated Zod schema; `'relaxed'` or `{ input: 'skip' }` skips validation entirely — use it for routes whose payload shape can't be modelled in TypeScript (third-party webhook fan-in, dynamic blobs). Honored identically by both the Socket.io and HTTP/SSE transports.
58
+ - **Optional `export const errorFormatter`** overrides the error envelope for this route only (falls back to the global `registerErrorFormatter`, then the framework default). Both transports honor it.
57
59
  - **Never `try/catch` manually.** Wrap async ops in `functions.tryCatch` (or the destructured `tryCatch` from `functions`) — the framework already wraps the whole `main()` in its own `tryCatch` for Sentry capture, but per-operation `tryCatch` lets you surface targeted error codes.
58
60
 
59
61
  ---