@hyperfixi/server-bridge 2.11.0 → 3.0.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.
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,126 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.0.0] - 2026-09-03
|
|
11
|
+
|
|
12
|
+
Full notes: [GitHub Releases](https://github.com/codetalcott/hyperfixi/releases/tag/v3.0.0).
|
|
13
|
+
|
|
14
|
+
One major, two themes. `@lokascript/i18n`'s grammar transformer is gone,
|
|
15
|
+
because `@lokascript/semantic` overtook it on every row of the translation
|
|
16
|
+
corpus (#973–#1001). And the engine-migration plan
|
|
17
|
+
(`docs-internal/ENGINE_MIGRATION_PLAN.md`) is complete: its last arc deleted
|
|
18
|
+
the exported dead code it had been carrying and collapsed the browser bundle
|
|
19
|
+
lineup to two names (#1099–#1105).
|
|
20
|
+
|
|
21
|
+
### ⚠ BREAKING
|
|
22
|
+
|
|
23
|
+
- **`@lokascript/i18n` no longer translates** (#1001). `translate()`, `toLocale()`,
|
|
24
|
+
`toEnglish()`, `GrammarTransformer` and `createTransformer` are deleted; the
|
|
25
|
+
package is per-language vocabulary and grammar profiles. Migrate to
|
|
26
|
+
`import { translate } from '@lokascript/semantic'` (same signature; it throws
|
|
27
|
+
on unparseable input where the transformer returned nonsense). The classic-i18n
|
|
28
|
+
browser bundle, `@hyperscript-tools/i18n` and `@lokascript/types-browser` drop
|
|
29
|
+
the same members (#998, #999); the patterns corpus writer is semantic-only (#1000).
|
|
30
|
+
- **The prebuilt browser bundles are two names** (#1105): `hyperfixi-hx.js`
|
|
31
|
+
(small: hybrid parser, blocks, expressions, htmx v1/v2 attributes) and
|
|
32
|
+
`hyperfixi.js` (everything); `hyperfixi-hx-v4.js` and
|
|
33
|
+
`hyperfixi-multilingual.js` stay as separate products. `hyperfixi-lite.js`,
|
|
34
|
+
`-lite-plus.js`, `-minimal.js`, `-standard.js` and their `./browser/*`
|
|
35
|
+
exports are gone — use `hyperfixi-hx.js`, `hyperfixi.js`, or the Vite
|
|
36
|
+
plugin, which picks the tier itself. `./browser/hybrid-complete` remains as
|
|
37
|
+
the plugin's internal fallback.
|
|
38
|
+
- **Exported dead code deleted from `@hyperfixi/core`** — none had a
|
|
39
|
+
production caller: the six `@deprecated` `features/` families and the
|
|
40
|
+
modular bundle's `features` namespace (#1099); `Lexer`/`Tokens` (#1100 —
|
|
41
|
+
use `tokenize`); the `unified-types` `Validator`, the `types.d.ts` shim and
|
|
42
|
+
`registry/multilingual` (#1101); the `async` command (#1102 — it was
|
|
43
|
+
unreachable from parsed hyperscript; the manifest is 58 commands);
|
|
44
|
+
`ContextProviderRegistry`, the context-provider `Proxy`, the registry's
|
|
45
|
+
`context` slot and the plugin `contextProviders` field (#1104 — set
|
|
46
|
+
request-scoped values as `context.locals`).
|
|
47
|
+
|
|
48
|
+
### Fixed
|
|
49
|
+
|
|
50
|
+
- **A small bundle fails loudly on a command it lacks and names `hyperfixi.js`**
|
|
51
|
+
(#1103). The hybrid parser had been dropping an unrecognised word silently;
|
|
52
|
+
making it loud also exposed and fixed three silent mis-parses in the hybrid
|
|
53
|
+
bundles: unquoted `fetch /api/data` fetched `/`, `send custom:event` sent
|
|
54
|
+
`custom` to `me`, and `repeat forever` ran zero iterations.
|
|
55
|
+
- **English→foreign rendering is gated** (#931–#972, #953): 3105/3105 corpus
|
|
56
|
+
renders parse on the canonical engine; the bare (handler-less) surface has its
|
|
57
|
+
own gate. `as JSON` stays part of the value (#991); a flattened loop header
|
|
58
|
+
closes (#992).
|
|
59
|
+
- Plugins report their real versions (#926); `analyze_content` is unshadowed in
|
|
60
|
+
the MCP server (#927); four dependency advisories resolved; the `domain-flow`
|
|
61
|
+
→ `server-bridge` route contract is pinned (#1000s).
|
|
62
|
+
|
|
63
|
+
### Changed
|
|
64
|
+
|
|
65
|
+
- `hyperfixi.js` and `hyperfixi-hx-v4.js` carry the 24-language render
|
|
66
|
+
vocabulary (~19 KB gzip each) so `translate` works in the browser (#931).
|
|
67
|
+
- Deprecated `@lokascript/domain-*` references repoint to `@lokascript/domains`.
|
|
68
|
+
|
|
69
|
+
## [2.11.1] - 2026-08-25
|
|
70
|
+
|
|
71
|
+
Patch release. Fixes the release workflow itself: the build now runs **after**
|
|
72
|
+
the version sync, so a published tarball carries its own version rather than
|
|
73
|
+
the previous one, and `version.ts` is committed (#925). Also lands the
|
|
74
|
+
agent-loop A/B benchmark with an isolated generator (#924).
|
|
75
|
+
|
|
76
|
+
## [2.11.0] - 2026-08-24
|
|
77
|
+
|
|
78
|
+
Full notes: [GitHub Releases](https://github.com/codetalcott/hyperfixi/releases/tag/v2.11.0).
|
|
79
|
+
|
|
80
|
+
### Changed
|
|
81
|
+
|
|
82
|
+
- **The domain-DSL family moved out** (#909). Twelve packages left this
|
|
83
|
+
monorepo: the ten publishable `@lokascript/domain-*` packages (bdd,
|
|
84
|
+
behaviorspec, config, flow, jsx, learn, llm, sql, todo, voice) plus the
|
|
85
|
+
private `domain-toolkit` and `mcp-multilingual-intent`. They now ship as
|
|
86
|
+
**`@lokascript/domains`**, one subpath export per domain, from the
|
|
87
|
+
[lokascript-domains](https://github.com/codetalcott/lokascript-domains)
|
|
88
|
+
repository.
|
|
89
|
+
|
|
90
|
+
All ten published names are **deprecated on npm**, each naming its
|
|
91
|
+
replacement subpath (`@lokascript/domain-sql` → "import from
|
|
92
|
+
`@lokascript/domains/sql`"). Existing installs keep working — deprecation is
|
|
93
|
+
a warning, not a removal — they simply stop receiving updates. The
|
|
94
|
+
pre-deletion tree is preserved at the `moved/domain-family` tag.
|
|
95
|
+
|
|
96
|
+
_Migration:_ replace nine dependencies with one, and change
|
|
97
|
+
`from '@lokascript/domain-x'` to `from '@lokascript/domains/x'`. The root
|
|
98
|
+
entry absorbed `domain-config` and exports `createDomainRegistry`,
|
|
99
|
+
`registerAllDomains` and `DOMAIN_PRIORITY`.
|
|
100
|
+
|
|
101
|
+
### Added
|
|
102
|
+
|
|
103
|
+
- **"Show in My Language"** — LSP request plus VSCode command (#921).
|
|
104
|
+
- **Verified-translation badge** in the compilation service (#920).
|
|
105
|
+
- **`scoreFidelity` / `@lokascript/semantic/fidelity`** (#919).
|
|
106
|
+
- **Inert-shape warnings** (#918) and surfaced unconsumed-input warnings (#916)
|
|
107
|
+
in the compilation service.
|
|
108
|
+
- **The agent-loop benchmark** and the silent-failure finding it produced
|
|
109
|
+
(#915), and the MCP server's agent-era roadmap (#914).
|
|
110
|
+
- **Element-collection write-back** for hypermedia tables, with gallery
|
|
111
|
+
examples and four system fixes (#904).
|
|
112
|
+
- **The comprehensive Playwright tier now runs in CI** (#908) alongside
|
|
113
|
+
`quick`. It had never run: 122 specs, hiding four real bugs — a detached
|
|
114
|
+
`startViewTransition`, untracked reads of unset globals, concurrent effects
|
|
115
|
+
clobbering dependency capture, and `put` stringifying DocumentFragments
|
|
116
|
+
(#905).
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
|
|
120
|
+
- **The `hyperscript-adapter` review arc** (#895–#902): whole-string
|
|
121
|
+
translation first, taking canonical validity from 2849/3105 to **3105/3105**
|
|
122
|
+
(#899); a host-parser validity gate so an invalid render falls back to the
|
|
123
|
+
author's text (#900); the dead split-statement fallback deleted after
|
|
124
|
+
measuring 0 outputs (#901); and the slim divergence set burned 6 → 1 via
|
|
125
|
+
schema marker data, repairing 39 body-dropping corpus rows (#902).
|
|
126
|
+
- **`qu take.recipient`** — the R1 tail's last `take` row (#910).
|
|
127
|
+
- **The release workflows** no longer reference the moved-out domain family
|
|
128
|
+
(#922).
|
|
129
|
+
|
|
10
130
|
## [2.10.0] - 2026-08-01
|
|
11
131
|
|
|
12
132
|
Full notes: [GitHub Releases](https://github.com/codetalcott/hyperfixi/releases/tag/v2.10.0).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time compatibility pin: domain-flow's `FlowRouteDescriptor` →
|
|
3
|
+
* server-bridge's `RouteDescriptor`.
|
|
4
|
+
*
|
|
5
|
+
* `@lokascript/domains/flow` declares its route descriptor as "compatible with
|
|
6
|
+
* server-bridge's RouteDescriptor but self-contained to avoid a hard dependency
|
|
7
|
+
* on the server-bridge package", and its route extractor exists so that
|
|
8
|
+
* "each fetch/poll/stream/submit URL becomes a RouteDescriptor that can be fed
|
|
9
|
+
* into server-bridge". Those two claims live in a different repository now.
|
|
10
|
+
* The adapter below is the only place either one is written as code rather than
|
|
11
|
+
* prose, so it is what keeps them honest.
|
|
12
|
+
*
|
|
13
|
+
* WHY THIS IS ORDINARY SOURCE AND NOT A TEST: the predecessor of this pin was
|
|
14
|
+
* `domain-flow/src/__test__/route-descriptor-compat.test.ts`, and it never
|
|
15
|
+
* checked anything. That package's tsconfig excluded `**\/*.test.ts` and
|
|
16
|
+
* `**\/__test__\/**`, so `tsc` never saw the `satisfies`; vitest strips types
|
|
17
|
+
* with esbuild rather than checking them. The assertion was erased at both
|
|
18
|
+
* gates. Here the file is inside `include: ["src/**\/*.ts"]`, so
|
|
19
|
+
* `npm run typecheck` compiles it: if either shape drifts — a new required
|
|
20
|
+
* field on `RouteDescriptor`, a widened method or response-format union on
|
|
21
|
+
* `FlowRouteDescriptor` — this stops compiling.
|
|
22
|
+
*
|
|
23
|
+
* The import is `import type`, so nothing here survives to runtime and
|
|
24
|
+
* `@lokascript/domains` stays a devDependency. Deliberately NOT re-exported
|
|
25
|
+
* from `index.ts`: server-bridge does not take a dependency on the domain
|
|
26
|
+
* family, it only promises to remain assignable from it.
|
|
27
|
+
*/
|
|
28
|
+
import type { FlowRouteDescriptor } from '@lokascript/domains/flow';
|
|
29
|
+
import type { RouteDescriptor, RouteSource } from '../types.js';
|
|
30
|
+
/**
|
|
31
|
+
* The documented adaptation: supply the provenance server-bridge requires
|
|
32
|
+
* (`source`, `notes`) and drop SSE routes, which server-bridge's
|
|
33
|
+
* `responseFormat` union does not model.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toServerBridgeRoute(flow: FlowRouteDescriptor, source: RouteSource): RouteDescriptor | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperfixi/server-bridge",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "Extract server route contracts from hyperscript/htmx HTML and generate server-side route scaffolding",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"glob": "^13.0.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
+
"@lokascript/domains": "^2.11.1",
|
|
32
33
|
"@types/node": "^26.1.2",
|
|
33
34
|
"tsup": "^8.0.0",
|
|
34
35
|
"typescript": "^5.0.0",
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime half of the domain-flow compatibility pin.
|
|
3
|
+
*
|
|
4
|
+
* The compile-time half — and the part that actually catches drift — lives in
|
|
5
|
+
* `src/compat/flow-route-descriptor.ts`, because this directory is excluded
|
|
6
|
+
* from the tsconfig and vitest strips types rather than checking them. Nothing
|
|
7
|
+
* asserted about a *type* in this file would be enforced; these cases cover the
|
|
8
|
+
* adapter's runtime behaviour only.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect } from 'vitest';
|
|
12
|
+
import type { FlowRouteDescriptor } from '@lokascript/domains/flow';
|
|
13
|
+
import { toServerBridgeRoute } from '../compat/flow-route-descriptor.js';
|
|
14
|
+
|
|
15
|
+
const source = { file: 'app.html', kind: 'fetch' as const, raw: 'fetch /api/users/{id} as json' };
|
|
16
|
+
|
|
17
|
+
describe('FlowRouteDescriptor → server-bridge RouteDescriptor', () => {
|
|
18
|
+
it('adapts a fetch route by supplying the two fields flow does not carry', () => {
|
|
19
|
+
const flow: FlowRouteDescriptor = {
|
|
20
|
+
path: '/api/users/{id}',
|
|
21
|
+
method: 'GET',
|
|
22
|
+
responseFormat: 'json',
|
|
23
|
+
pathParams: ['id'],
|
|
24
|
+
handlerName: 'getUsersId',
|
|
25
|
+
sourceCommand: 'fetch',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const route = toServerBridgeRoute(flow, source);
|
|
29
|
+
|
|
30
|
+
expect(route).not.toBeNull();
|
|
31
|
+
expect(route!.path).toBe('/api/users/{id}');
|
|
32
|
+
expect(route!.method).toBe('GET');
|
|
33
|
+
expect(route!.responseFormat).toBe('json');
|
|
34
|
+
expect(route!.pathParams).toEqual(['id']);
|
|
35
|
+
expect(route!.handlerName).toBe('getUsersId');
|
|
36
|
+
expect(route!.source).toEqual(source);
|
|
37
|
+
expect(route!.notes).toEqual([]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('drops SSE routes — server-bridge has no sse response format', () => {
|
|
41
|
+
const flow: FlowRouteDescriptor = {
|
|
42
|
+
path: '/api/events',
|
|
43
|
+
method: 'GET',
|
|
44
|
+
responseFormat: 'sse',
|
|
45
|
+
pathParams: [],
|
|
46
|
+
handlerName: 'getEvents',
|
|
47
|
+
sourceCommand: 'stream',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
expect(toServerBridgeRoute(flow, source)).toBeNull();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('carries every non-sse response format through unchanged', () => {
|
|
54
|
+
for (const format of ['json', 'html', 'text'] as const) {
|
|
55
|
+
const flow: FlowRouteDescriptor = {
|
|
56
|
+
path: '/api/thing',
|
|
57
|
+
method: 'POST',
|
|
58
|
+
responseFormat: format,
|
|
59
|
+
pathParams: [],
|
|
60
|
+
handlerName: 'postThing',
|
|
61
|
+
sourceCommand: 'submit',
|
|
62
|
+
};
|
|
63
|
+
expect(toServerBridgeRoute(flow, source)?.responseFormat).toBe(format);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compile-time compatibility pin: domain-flow's `FlowRouteDescriptor` →
|
|
3
|
+
* server-bridge's `RouteDescriptor`.
|
|
4
|
+
*
|
|
5
|
+
* `@lokascript/domains/flow` declares its route descriptor as "compatible with
|
|
6
|
+
* server-bridge's RouteDescriptor but self-contained to avoid a hard dependency
|
|
7
|
+
* on the server-bridge package", and its route extractor exists so that
|
|
8
|
+
* "each fetch/poll/stream/submit URL becomes a RouteDescriptor that can be fed
|
|
9
|
+
* into server-bridge". Those two claims live in a different repository now.
|
|
10
|
+
* The adapter below is the only place either one is written as code rather than
|
|
11
|
+
* prose, so it is what keeps them honest.
|
|
12
|
+
*
|
|
13
|
+
* WHY THIS IS ORDINARY SOURCE AND NOT A TEST: the predecessor of this pin was
|
|
14
|
+
* `domain-flow/src/__test__/route-descriptor-compat.test.ts`, and it never
|
|
15
|
+
* checked anything. That package's tsconfig excluded `**\/*.test.ts` and
|
|
16
|
+
* `**\/__test__\/**`, so `tsc` never saw the `satisfies`; vitest strips types
|
|
17
|
+
* with esbuild rather than checking them. The assertion was erased at both
|
|
18
|
+
* gates. Here the file is inside `include: ["src/**\/*.ts"]`, so
|
|
19
|
+
* `npm run typecheck` compiles it: if either shape drifts — a new required
|
|
20
|
+
* field on `RouteDescriptor`, a widened method or response-format union on
|
|
21
|
+
* `FlowRouteDescriptor` — this stops compiling.
|
|
22
|
+
*
|
|
23
|
+
* The import is `import type`, so nothing here survives to runtime and
|
|
24
|
+
* `@lokascript/domains` stays a devDependency. Deliberately NOT re-exported
|
|
25
|
+
* from `index.ts`: server-bridge does not take a dependency on the domain
|
|
26
|
+
* family, it only promises to remain assignable from it.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import type { FlowRouteDescriptor } from '@lokascript/domains/flow';
|
|
30
|
+
import type { RouteDescriptor, RouteSource } from '../types.js';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The documented adaptation: supply the provenance server-bridge requires
|
|
34
|
+
* (`source`, `notes`) and drop SSE routes, which server-bridge's
|
|
35
|
+
* `responseFormat` union does not model.
|
|
36
|
+
*/
|
|
37
|
+
export function toServerBridgeRoute(
|
|
38
|
+
flow: FlowRouteDescriptor,
|
|
39
|
+
source: RouteSource
|
|
40
|
+
): RouteDescriptor | null {
|
|
41
|
+
if (flow.responseFormat === 'sse') return null;
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
path: flow.path,
|
|
45
|
+
method: flow.method,
|
|
46
|
+
responseFormat: flow.responseFormat,
|
|
47
|
+
pathParams: flow.pathParams,
|
|
48
|
+
handlerName: flow.handlerName,
|
|
49
|
+
source,
|
|
50
|
+
notes: [],
|
|
51
|
+
} satisfies RouteDescriptor;
|
|
52
|
+
}
|