@abide/abide 0.116.1 → 0.116.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @abide/abide
2
2
 
3
+ ## 0.116.2
4
+
5
+ ### Patch Changes
6
+
7
+ - ef77e8d: a comment directly above an at-rule in a component's `<style>` no longer breaks its scoping — `/* … */ @media (…) { .x {…} }` scopes `.x` as it would with no comment
8
+ - 99631d1: the registry names `isFailed`, says `route.url` includes the fragment and `route.name` is the same under any mount path, and shows a `GET` over a plain function or a value taking `ReactiveOptions`; a scaffolded app's AGENTS.md names the `abide-ignore` escape, exporting a `Reactive` unwrapped, never `raw()` on untrusted markup, and `config` / `cookies()` over `Bun.env` and header parsing
9
+
3
10
  ## 0.116.1
4
11
 
5
12
  ### Patch Changes
package/docs/REGISTRY.md CHANGED
@@ -183,6 +183,7 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
183
183
  | `refuse.named` | `<Name extends string>(name: Name, status?: number, message?: string) => ((data?: undefined) => Failed<Name, undefined>) & { is: (error: unknown) => error is Failed<Name, undefined> }` | A reusable factory for a named, narrowable failure. | 15.3, 15.13, 15.18 |
184
184
  | `refuse.named` | `<Name extends string, Data extends JsonValue>(name: Name, status: number \| undefined, message: string \| ((data: Data) => string) \| undefined, options: { schema: Schema<Data> }) => ((data?: Data) => Failed<Name, Data>) & { is: (error: unknown) => error is Failed<Name, Data> }` | The same, carrying data its schema declares. | 15.3, 15.11, 15.12, 15.13, 15.14, 15.15, 15.18 |
185
185
  | `Failed<Name, Data>` | `Error & { name: Name; status: number; message: string; data: Data }` | The one refusal type, in-process and over a wire alike. | 15.1, 15.2, 15.6, 16.40, 16.41, 15.21 |
186
+ | `isFailed` | `(value: unknown) => value is Failed<string, unknown>` | Whether a value is a refusal. | 15.6 |
186
187
  | `return myError(data)` | `Failed<Name, Data>` | The one spelling for every refusal. | 15.4, 15.5 |
187
188
  | `notFound` | `(data?: { path: string; method: string }) => Failed<'NotFound', { path: string; method: string }>` | abide's own refusal for an address nothing answers. | 15.7, 15.9, 15.22 |
188
189
  | `validationError` | `<T>(data?: Issues<T>) => Failed<'ValidationError', Issues<T>>` | abide's own refusal for a schema or an `args` gate that refused, or a call's route parameter no segment can spell. | 15.8, 15.9 |
@@ -219,8 +220,8 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
219
220
  | `Args` | `Record<string, JsonValue> \| undefined` | The arguments, in the body on a mutation and in the URL on a `GET` or `DELETE`. | 11.24, 16.18, 19.15 |
220
221
  | `Middleware` | `<Ctx, Result>(next: (ctx?: Ctx) => Promise<Result>, ctx: Ctx) => Result \| Promise<Result>` | One rung of `middleware`. | 16.14, 16.15, 16.16, 16.21 |
221
222
  | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: Reactive<Value, Value, Failures, Produced> \| Keyed<Value, Args, Value, Failures, Produced>, options?: RpcOptions<Args, RungFailures>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | Declares a read any surface may call. | 16.1, 16.2, 16.5, 16.6, 16.30, 16.31, 16.32, 16.68, 16.76, 16.34, 16.35, 16.36, 16.37, 16.39, 16.44, 16.45, 16.46, 16.47, 16.75, 16.50, 16.51, 16.52, 16.64, 18.1, 18.3, 18.6, 18.8, 18.10, 18.12, 18.21, 18.24, 18.27 |
222
- | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: (args?: Args) => Value, options?: RpcOptions<Args, RungFailures> & ReactiveOptions<Value, Value, Failures, Args>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | The plain-function overload, whose options build the value it becomes beside its address. | 16.1, 16.6, 16.7 |
223
- | `GET` | `<Value, Failures, RungFailures>(handler: Value \| PromiseLike<Value>, options?: RpcOptions<undefined, RungFailures> & ReactiveOptions<Value, Value, Failures>) => Rpc<Value, undefined, Failures \| RungFailures>` | The value overload, for what the handler owns outright. | 16.1, 16.6, 16.7 |
223
+ | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: (args?: Args) => Value, options?: RpcOptions<Args, RungFailures> & ReactiveOptions<Value, Value, Failures, Args>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | The plain-function overload, whose `ReactiveOptions` (`ttl`, `global`, `debounce` and the rest) build the value it becomes beside its address. | 16.1, 16.6, 16.7 |
224
+ | `GET` | `<Value, Failures, RungFailures>(handler: Value \| PromiseLike<Value>, options?: RpcOptions<undefined, RungFailures> & ReactiveOptions<Value, Value, Failures>) => Rpc<Value, undefined, Failures \| RungFailures>` | The value overload, for what the handler owns outright, whose `ReactiveOptions` build the value it becomes. | 16.1, 16.6, 16.7 |
224
225
  | `POST` / `PUT` / `PATCH` / `DELETE` | same as `GET` | Declares a mutation. | 16.2, 16.7, 16.32, 16.68, 16.76, 16.38, 16.53 |
225
226
  | `rpc.busy` | `(pattern?: Partial<Args>) => boolean` | `busy` narrowed to the handler's matching entries. | 13.2, 13.3, 13.12, 46.11 |
226
227
  | `rpc.ready` | `(pattern?: Partial<Args>) => boolean` | `ready` narrowed to the handler's matching entries. | 13.11, 13.12 |
@@ -379,10 +380,10 @@ type Gated<Gate, Accepted> = [Schema<Accepted>] extends [Gate] ? never : Failed<
379
380
 
380
381
  | Name | Signature | Meaning | Rules |
381
382
  | --- | --- | --- | --- |
382
- | `route.url` | `Reactive<URL>` | Where we are. | 23.1, 23.2, 23.3, 23.4, 30.23, 19.16, 31.16 |
383
+ | `route.url` | `Reactive<URL>` | Where we are, fragment included. | 23.1, 23.2, 23.3, 23.4, 30.20, 30.21, 30.23, 19.16, 31.16 |
383
384
  | `route.params` | `Reactive<Params>` | The matched route's segments. | 23.1, 23.5, 23.9, 30.23, 31.16 |
384
385
  | `Params` | `Record<string, string \| string[]>` | What a matched route's segments are. | 23.5 |
385
- | `route.name` | `Reactive<string>` | The resolution path. | 23.1, 23.6, 31.16 |
386
+ | `route.name` | `Reactive<string>` | The resolution path, the same under any mount path. | 23.1, 23.6, 23.14, 31.16 |
386
387
  | `route.navigating` | `Reactive<boolean>` | Whether a navigation is in flight. | 23.1, 31.16 |
387
388
 
388
389
  ## `online`
package/docs/abide.md CHANGED
@@ -43,6 +43,7 @@ at its address with `.md` on the end, and the links below point at those files.
43
43
  - `invalidate` — `reference/invalidate.md`
44
44
  - `refuse` — `reference/refuse.md`
45
45
  - `Failed` — `reference/types/Failed.md`
46
+ - `isFailed` — `reference/isFailed.md`
46
47
  - `notFound` — `reference/notFound.md`
47
48
  - `validationError` — `reference/validationError.md`
48
49
  - `aborted` — `reference/aborted.md`
@@ -439,7 +440,7 @@ let starred = reactive(false)
439
440
  </script>
440
441
 
441
442
  <div class="row">
442
- <button aria-pressed={String(starred)} onclick={() => (starred = !starred)}>
443
+ <button aria-pressed={starred} onclick={() => (starred = !starred)}>
443
444
  {starred ? '★ Starred' : '☆ Star'}
444
445
  </button>
445
446
  <span>Grace Hopper</span>
@@ -2135,7 +2136,7 @@ const { id, name } = props<{ id: string; name: string }>()
2135
2136
  let selected = reactive.share('selectedDeal', () => reactive(''))
2136
2137
  </script>
2137
2138
 
2138
- <button aria-pressed={String(selected === id)} onclick={() => (selected = id)}>
2139
+ <button aria-pressed={selected === id} onclick={() => (selected = id)}>
2139
2140
  {name}
2140
2141
  </button>
2141
2142
  ```
@@ -2939,7 +2940,7 @@ const address = reactive(() => url('/companies/[id]', { id: open }))
2939
2940
 
2940
2941
  <div class="tabs">
2941
2942
  {#for id of IDS}
2942
- <button aria-selected={String(open === id)}
2943
+ <button aria-selected={open === id}
2943
2944
  onclick={() => (open = id)}>{id}</button>
2944
2945
  {/for}
2945
2946
  </div>
@@ -3087,7 +3088,7 @@ let draft = reactive('')
3087
3088
 
3088
3089
  <div class="tabs">
3089
3090
  {#for name of TABS}
3090
- <button aria-selected={String(tab === name)}
3091
+ <button aria-selected={tab === name}
3091
3092
  onclick={() => navigate(`?tab=${name}`, { replace: true })}
3092
3093
  >{name}</button>
3093
3094
  {/for}
@@ -3236,7 +3237,7 @@ function followTitle(element: Element) {
3236
3237
 
3237
3238
  <div class="tabs">
3238
3239
  {#for page of PAGES}
3239
- <button aria-selected={String(open === page.address)}
3240
+ <button aria-selected={open === page.address}
3240
3241
  onclick={() => (open = page.address)}>{page.label}</button>
3241
3242
  {/for}
3242
3243
  </div>
@@ -5678,6 +5679,7 @@ import { claudeCode, GET } from '@abide/abide/server'
5678
5679
  // This browser's pairing, for as long as the page watches it.
5679
5680
  export default GET(() => claudeCode.bridge(), {
5680
5681
  description: "This browser's Claude Code pairing, as it changes.",
5682
+ // Exempt from an operator's ABIDE_RPC_TIMEOUT: a pairing idles for minutes.
5681
5683
  timeout: Infinity,
5682
5684
  clients: { mcp: false },
5683
5685
  })
@@ -6596,6 +6598,7 @@ Arrive here knowing which name you want. Each page is read off the registry: the
6596
6598
  | [`invalidate`](/reference/invalidate.md) | `@abide/abide` |
6597
6599
  | [`refuse`](/reference/refuse.md) | `@abide/abide` |
6598
6600
  | [`Failed`](/reference/types/Failed.md) | `@abide/abide` |
6601
+ | [`isFailed`](/reference/isFailed.md) | `@abide/abide` |
6599
6602
  | [`notFound`](/reference/notFound.md) | `@abide/abide` |
6600
6603
  | [`validationError`](/reference/validationError.md) | `@abide/abide` |
6601
6604
  | [`aborted`](/reference/aborted.md) | `@abide/abide` |
@@ -7289,6 +7292,24 @@ Arrive here knowing which name you want. Each page is read off the registry: the
7289
7292
 
7290
7293
  ---
7291
7294
 
7295
+ <!-- reference/isFailed.md -->
7296
+
7297
+ # `isFailed`
7298
+
7299
+ `import { isFailed } from '@abide/abide'`
7300
+
7301
+ ## Refusals
7302
+
7303
+ | Name | Signature | Meaning | Rules |
7304
+ | --- | --- | --- | --- |
7305
+ | `isFailed` | `(value: unknown) => value is Failed<string, unknown>` | Whether a value is a refusal. | [15.6](/rulebook#15.6) |
7306
+
7307
+ ## Taught in
7308
+
7309
+ - [Add pages](/guide/add-pages.md)
7310
+
7311
+ ---
7312
+
7292
7313
  <!-- reference/notFound.md -->
7293
7314
 
7294
7315
  # `notFound`
@@ -7441,8 +7462,8 @@ Reactive primitives: what is written in place rather than imported.
7441
7462
  | Name | Signature | Meaning | Rules |
7442
7463
  | --- | --- | --- | --- |
7443
7464
  | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: Reactive<Value, Value, Failures, Produced> \| Keyed<Value, Args, Value, Failures, Produced>, options?: RpcOptions<Args, RungFailures>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | Declares a read any surface may call. | [16.1](/rulebook#16.1), [16.2](/rulebook#16.2), [16.5](/rulebook#16.5), [16.6](/rulebook#16.6), [16.30](/rulebook#16.30), [16.31](/rulebook#16.31), [16.32](/rulebook#16.32), [16.68](/rulebook#16.68), [16.76](/rulebook#16.76), [16.34](/rulebook#16.34), [16.35](/rulebook#16.35), [16.36](/rulebook#16.36), [16.37](/rulebook#16.37), [16.39](/rulebook#16.39), [16.44](/rulebook#16.44), [16.45](/rulebook#16.45), [16.46](/rulebook#16.46), [16.47](/rulebook#16.47), [16.75](/rulebook#16.75), [16.50](/rulebook#16.50), [16.51](/rulebook#16.51), [16.52](/rulebook#16.52), [16.64](/rulebook#16.64), [18.1](/rulebook#18.1), [18.3](/rulebook#18.3), [18.6](/rulebook#18.6), [18.8](/rulebook#18.8), [18.10](/rulebook#18.10), [18.12](/rulebook#18.12), [18.21](/rulebook#18.21), [18.24](/rulebook#18.24), [18.27](/rulebook#18.27) |
7444
- | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: (args?: Args) => Value, options?: RpcOptions<Args, RungFailures> & ReactiveOptions<Value, Value, Failures, Args>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | The plain-function overload, whose options build the value it becomes beside its address. | [16.1](/rulebook#16.1), [16.6](/rulebook#16.6), [16.7](/rulebook#16.7) |
7445
- | `GET` | `<Value, Failures, RungFailures>(handler: Value \| PromiseLike<Value>, options?: RpcOptions<undefined, RungFailures> & ReactiveOptions<Value, Value, Failures>) => Rpc<Value, undefined, Failures \| RungFailures>` | The value overload, for what the handler owns outright. | [16.1](/rulebook#16.1), [16.6](/rulebook#16.6), [16.7](/rulebook#16.7) |
7465
+ | `GET` | `<Value, Args, Failures, RungFailures, Produced = Value>(handler: (args?: Args) => Value, options?: RpcOptions<Args, RungFailures> & ReactiveOptions<Value, Value, Failures, Args>) => Rpc<Value, Args, Failures \| RungFailures, Produced>` | The plain-function overload, whose `ReactiveOptions` (`ttl`, `global`, `debounce` and the rest) build the value it becomes beside its address. | [16.1](/rulebook#16.1), [16.6](/rulebook#16.6), [16.7](/rulebook#16.7) |
7466
+ | `GET` | `<Value, Failures, RungFailures>(handler: Value \| PromiseLike<Value>, options?: RpcOptions<undefined, RungFailures> & ReactiveOptions<Value, Value, Failures>) => Rpc<Value, undefined, Failures \| RungFailures>` | The value overload, for what the handler owns outright, whose `ReactiveOptions` build the value it becomes. | [16.1](/rulebook#16.1), [16.6](/rulebook#16.6), [16.7](/rulebook#16.7) |
7446
7467
 
7447
7468
  ## Taught in
7448
7469
 
@@ -8175,9 +8196,9 @@ Generated surfaces: what is written in place rather than imported.
8175
8196
 
8176
8197
  | Name | Signature | Meaning | Rules |
8177
8198
  | --- | --- | --- | --- |
8178
- | `route.url` | `Reactive<URL>` | Where we are. | [23.1](/rulebook#23.1), [23.2](/rulebook#23.2), [23.3](/rulebook#23.3), [23.4](/rulebook#23.4), [30.23](/rulebook#30.23), [19.16](/rulebook#19.16), [31.16](/rulebook#31.16) |
8199
+ | `route.url` | `Reactive<URL>` | Where we are, fragment included. | [23.1](/rulebook#23.1), [23.2](/rulebook#23.2), [23.3](/rulebook#23.3), [23.4](/rulebook#23.4), [30.20](/rulebook#30.20), [30.21](/rulebook#30.21), [30.23](/rulebook#30.23), [19.16](/rulebook#19.16), [31.16](/rulebook#31.16) |
8179
8200
  | `route.params` | `Reactive<Params>` | The matched route's segments. | [23.1](/rulebook#23.1), [23.5](/rulebook#23.5), [23.9](/rulebook#23.9), [30.23](/rulebook#30.23), [31.16](/rulebook#31.16) |
8180
- | `route.name` | `Reactive<string>` | The resolution path. | [23.1](/rulebook#23.1), [23.6](/rulebook#23.6), [31.16](/rulebook#31.16) |
8201
+ | `route.name` | `Reactive<string>` | The resolution path, the same under any mount path. | [23.1](/rulebook#23.1), [23.6](/rulebook#23.6), [23.14](/rulebook#23.14), [31.16](/rulebook#31.16) |
8181
8202
  | `route.navigating` | `Reactive<boolean>` | Whether a navigation is in flight. | [23.1](/rulebook#23.1), [31.16](/rulebook#31.16) |
8182
8203
 
8183
8204
  ## Taught in
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abide/abide",
3
- "version": "0.116.1",
3
+ "version": "0.116.2",
4
4
  "type": "module",
5
5
  "description": "Isomorphic type-safe framework for reactive async interfaces for humans and machines",
6
6
  "license": "MIT",
@@ -17,6 +17,9 @@ before writing code, rather than guessing from Svelte, Vue or React. It installs
17
17
  TypeScript service do not read `.abide` files, so a clean `tsc` says nothing about them. Run
18
18
  `bun run check` after every change, and treat its warnings as bugs: several of them name a read
19
19
  that will not update when its value changes.
20
+ Where the read is meant, `// abide-ignore` and the clause the warning cites, on the line above
21
+ (`// abide-ignore 14.15`), silences that one (RULEBOOK 14.19); a read hoisted out of its place
22
+ only to quiet a warning is the bug it named.
20
23
  - `bun run test` — runs `bun test`. `src/getGreeting.test.ts` is the pattern: a test imports a
21
24
  handler or a `.abide` file and calls it.
22
25
  - `bun run dev` — serves the app on a local port and rebuilds when a file changes.
@@ -44,3 +47,12 @@ before writing code, rather than guessing from Svelte, Vue or React. It installs
44
47
  - Import the app's own modules as `#src/…` (see `imports` in `package.json`).
45
48
  - A test imports `.abide` files directly: `bunfig.toml` preloads `@abide/harness/abide/preload`,
46
49
  a DOM to mount into and then `@abide/abide/test`.
50
+
51
+ ## Habits
52
+
53
+ - Export a `Reactive` itself, never wrapped in an object: an `.abide` file reads and writes it by
54
+ name (RULEBOOK 31.1), and one reached through a property is left to `x()` and `x.set(v)` (31.7).
55
+ - Model output and fetched HTML are untrusted. Never hand them to `raw()` (RULEBOOK 32.2)
56
+ unsanitized.
57
+ - Settings come from `onConfig` and `config` (RULEBOOK 27.2, 27.9), which already read the
58
+ environment, and cookies from `cookies()` (22.2) — not `Bun.env` or a parsed `cookie` header.
@@ -122,6 +122,9 @@ export function namesViewTransition(css: string): boolean {
122
122
  return false
123
123
  }
124
124
 
125
+ // Whitespace and comments ahead of a statement, which do not decide whether it is an at-rule.
126
+ const LEADING_COMMENTS = /^(?:\s|\/\*[\s\S]*?\*\/)*/
127
+
125
128
  // The block at-rules that hold rules, which `scopeRules` walks into.
126
129
  const NESTING =
127
130
  /^@(media|supports|container|layer|document|starting-style|scope)\b/i
@@ -155,7 +158,7 @@ function scopeRules(css: string, attribute: string): string {
155
158
  }
156
159
  const close = matching(css, open)
157
160
  const body = css.slice(open + 1, close)
158
- const trimmed = prelude.trim()
161
+ const trimmed = prelude.replace(LEADING_COMMENTS, '').trim()
159
162
  if (trimmed.startsWith('@'))
160
163
  out += NESTING.test(trimmed)
161
164
  ? `${prelude}{${scopeRules(body, attribute)}}`