toiljs 0.0.115 → 0.0.117

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 (326) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +16 -7
  3. package/TYPESCRIPT_LAW.md +1946 -2073
  4. package/build/backend/.tsbuildinfo +1 -1
  5. package/build/cli/.tsbuildinfo +1 -1
  6. package/build/cli/index.js +2375 -258
  7. package/build/client/.tsbuildinfo +1 -1
  8. package/build/client/dev/devtools.js +1 -1
  9. package/build/client/dev/error-overlay.js +1 -1
  10. package/build/client/routing/mount.js +1 -1
  11. package/build/compiler/.tsbuildinfo +1 -1
  12. package/build/compiler/auth-emails.js +7 -3
  13. package/build/compiler/emails.js +1 -1
  14. package/build/compiler/index.d.ts +1 -0
  15. package/build/compiler/index.js +25 -4
  16. package/build/compiler/pages.js +2 -3
  17. package/build/compiler/prerender.d.ts +3 -8
  18. package/build/compiler/prerender.js +88 -127
  19. package/build/compiler/ssg.js +3 -4
  20. package/build/compiler/template-build.js +3 -4
  21. package/build/compiler/toil-docs.generated.js +6 -5
  22. package/build/compiler/vite.js +3 -6
  23. package/build/devserver/.tsbuildinfo +1 -1
  24. package/build/devserver/db/database.js +7 -3
  25. package/build/devserver/db/types.js +1 -1
  26. package/build/devserver/production.js +4 -3
  27. package/build/devserver/runtime/crypto.d.ts +1 -1
  28. package/build/io/.tsbuildinfo +1 -1
  29. package/build/logger/.tsbuildinfo +1 -1
  30. package/build/shared/.tsbuildinfo +1 -1
  31. package/examples/basic/client/routes/analytics.tsx +7 -5
  32. package/examples/basic/server/tsconfig.json +1 -3
  33. package/package.json +45 -44
  34. package/presets/no-uint8array-tostring.js +120 -153
  35. package/presets/oxlint.d.ts +5 -0
  36. package/presets/oxlint.js +224 -0
  37. package/server/runtime/tsconfig.json +1 -3
  38. package/tsconfig.json +2 -11
  39. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
  40. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -90
  41. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  42. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  43. package/.github/PULL_REQUEST_TEMPLATE.md +0 -43
  44. package/.github/changelog-config.json +0 -45
  45. package/.github/dependabot.yml +0 -27
  46. package/.github/workflows/ci.yml +0 -222
  47. package/.vscode/settings.json +0 -10
  48. package/docs/README.md +0 -107
  49. package/docs/auth/README.md +0 -104
  50. package/docs/auth/configuration.md +0 -105
  51. package/docs/auth/emails.md +0 -92
  52. package/docs/auth/extending.md +0 -202
  53. package/docs/auth/how-it-works.md +0 -138
  54. package/docs/auth/usage.md +0 -188
  55. package/docs/backend/README.md +0 -143
  56. package/docs/backend/data.md +0 -351
  57. package/docs/backend/rest.md +0 -402
  58. package/docs/backend/rpc.md +0 -226
  59. package/docs/background/README.md +0 -114
  60. package/docs/background/daemons.md +0 -276
  61. package/docs/background/derive.md +0 -179
  62. package/docs/cli/README.md +0 -379
  63. package/docs/concepts/ai-guide.md +0 -132
  64. package/docs/concepts/config.md +0 -416
  65. package/docs/concepts/decorators.md +0 -127
  66. package/docs/concepts/security.md +0 -108
  67. package/docs/concepts/tiers.md +0 -166
  68. package/docs/concepts/types.md +0 -216
  69. package/docs/database/README.md +0 -143
  70. package/docs/database/capacity.md +0 -350
  71. package/docs/database/counters.md +0 -174
  72. package/docs/database/documents.md +0 -277
  73. package/docs/database/events.md +0 -307
  74. package/docs/database/membership.md +0 -246
  75. package/docs/database/setup.md +0 -155
  76. package/docs/database/unique.md +0 -216
  77. package/docs/database/views.md +0 -246
  78. package/docs/frontend/README.md +0 -104
  79. package/docs/frontend/components.md +0 -286
  80. package/docs/frontend/data-fetching.md +0 -260
  81. package/docs/frontend/images.md +0 -148
  82. package/docs/frontend/metadata.md +0 -344
  83. package/docs/frontend/navigation.md +0 -296
  84. package/docs/frontend/rendering.md +0 -236
  85. package/docs/frontend/routing.md +0 -346
  86. package/docs/frontend/scripts.md +0 -118
  87. package/docs/frontend/search.md +0 -191
  88. package/docs/frontend/styling.md +0 -147
  89. package/docs/frontend/toil-global.md +0 -216
  90. package/docs/getting-started/README.md +0 -81
  91. package/docs/getting-started/create-project.md +0 -131
  92. package/docs/getting-started/deploy.md +0 -101
  93. package/docs/getting-started/first-app.md +0 -215
  94. package/docs/getting-started/installation.md +0 -124
  95. package/docs/getting-started/migrating.md +0 -125
  96. package/docs/getting-started/project-structure.md +0 -163
  97. package/docs/introduction/README.md +0 -66
  98. package/docs/introduction/design-principles.md +0 -81
  99. package/docs/introduction/distributed.md +0 -91
  100. package/docs/introduction/how-it-works.md +0 -121
  101. package/docs/introduction/hyperscale.md +0 -70
  102. package/docs/introduction/modern-stack.md +0 -85
  103. package/docs/introduction/vs-other-frameworks.md +0 -64
  104. package/docs/introduction/why-toil.md +0 -99
  105. package/docs/llms.txt +0 -95
  106. package/docs/realtime/README.md +0 -102
  107. package/docs/realtime/channels.md +0 -211
  108. package/docs/realtime/streams.md +0 -369
  109. package/docs/services/README.md +0 -60
  110. package/docs/services/analytics.md +0 -279
  111. package/docs/services/caching.md +0 -175
  112. package/docs/services/cookies.md +0 -235
  113. package/docs/services/crypto.md +0 -209
  114. package/docs/services/email.md +0 -289
  115. package/docs/services/environment.md +0 -141
  116. package/docs/services/ratelimit.md +0 -174
  117. package/docs/services/time.md +0 -85
  118. package/eslint.config.js +0 -57
  119. package/examples/basic/client/routes/docs/[...slug].tsx +0 -12
  120. package/presets/eslint.js +0 -88
  121. package/src/backend/index.ts +0 -204
  122. package/src/cli/configure.ts +0 -363
  123. package/src/cli/create.ts +0 -924
  124. package/src/cli/db.ts +0 -158
  125. package/src/cli/diagnostics.ts +0 -665
  126. package/src/cli/doctor.ts +0 -982
  127. package/src/cli/features.ts +0 -170
  128. package/src/cli/index.ts +0 -326
  129. package/src/cli/notify.ts +0 -120
  130. package/src/cli/proc.ts +0 -56
  131. package/src/cli/ui.ts +0 -169
  132. package/src/cli/update.ts +0 -248
  133. package/src/cli/updates.ts +0 -92
  134. package/src/cli/validate.ts +0 -31
  135. package/src/cli/version-check.ts +0 -125
  136. package/src/client/auth.ts +0 -869
  137. package/src/client/channel/channel.ts +0 -146
  138. package/src/client/components/Form.tsx +0 -65
  139. package/src/client/components/Image.tsx +0 -160
  140. package/src/client/components/Script.tsx +0 -113
  141. package/src/client/components/Slot.tsx +0 -21
  142. package/src/client/dev/devtools.tsx +0 -1089
  143. package/src/client/dev/error-overlay.tsx +0 -225
  144. package/src/client/errors.ts +0 -11
  145. package/src/client/head/head.ts +0 -182
  146. package/src/client/head/metadata.ts +0 -110
  147. package/src/client/index.ts +0 -130
  148. package/src/client/navigation/Link.tsx +0 -108
  149. package/src/client/navigation/NavLink.tsx +0 -86
  150. package/src/client/navigation/navigation.ts +0 -235
  151. package/src/client/navigation/prefetch.ts +0 -169
  152. package/src/client/navigation/scroll.ts +0 -53
  153. package/src/client/routing/Router.tsx +0 -216
  154. package/src/client/routing/action.ts +0 -122
  155. package/src/client/routing/error-boundary.tsx +0 -43
  156. package/src/client/routing/hooks.ts +0 -140
  157. package/src/client/routing/lazy.ts +0 -77
  158. package/src/client/routing/loader.ts +0 -381
  159. package/src/client/routing/match.ts +0 -47
  160. package/src/client/routing/mount.tsx +0 -90
  161. package/src/client/routing/params-context.ts +0 -10
  162. package/src/client/routing/slot-context.ts +0 -7
  163. package/src/client/rpc.ts +0 -97
  164. package/src/client/search/search.ts +0 -189
  165. package/src/client/search/use-page-search.ts +0 -73
  166. package/src/client/ssr/markers.tsx +0 -172
  167. package/src/client/stream/client.ts +0 -237
  168. package/src/client/types.ts +0 -73
  169. package/src/compiler/auth-emails.ts +0 -312
  170. package/src/compiler/config.ts +0 -369
  171. package/src/compiler/docs.ts +0 -127
  172. package/src/compiler/email-preview.ts +0 -314
  173. package/src/compiler/emails.ts +0 -404
  174. package/src/compiler/fonts.ts +0 -89
  175. package/src/compiler/generate.ts +0 -471
  176. package/src/compiler/image-blur.ts +0 -42
  177. package/src/compiler/image-report.ts +0 -88
  178. package/src/compiler/index.ts +0 -1362
  179. package/src/compiler/pages.ts +0 -49
  180. package/src/compiler/plugin.ts +0 -391
  181. package/src/compiler/prerender.ts +0 -263
  182. package/src/compiler/routes.ts +0 -170
  183. package/src/compiler/seo.ts +0 -415
  184. package/src/compiler/sri.ts +0 -144
  185. package/src/compiler/ssg.ts +0 -177
  186. package/src/compiler/ssr-codegen.ts +0 -85
  187. package/src/compiler/template-build.ts +0 -676
  188. package/src/compiler/template.ts +0 -262
  189. package/src/compiler/toil-docs.generated.ts +0 -77
  190. package/src/compiler/vite.ts +0 -245
  191. package/src/devserver/analytics/index.ts +0 -317
  192. package/src/devserver/config/dotenv.ts +0 -102
  193. package/src/devserver/config/env.ts +0 -30
  194. package/src/devserver/config/ratelimit.ts +0 -123
  195. package/src/devserver/daemon/catalog.ts +0 -120
  196. package/src/devserver/daemon/cron.ts +0 -87
  197. package/src/devserver/daemon/host.ts +0 -134
  198. package/src/devserver/daemon/index.ts +0 -369
  199. package/src/devserver/daemon/runtime.ts +0 -48
  200. package/src/devserver/db/catalog.ts +0 -109
  201. package/src/devserver/db/database.ts +0 -1834
  202. package/src/devserver/db/derives.ts +0 -121
  203. package/src/devserver/db/index.ts +0 -20
  204. package/src/devserver/db/routeKinds.ts +0 -191
  205. package/src/devserver/db/types.ts +0 -168
  206. package/src/devserver/email/caps.ts +0 -0
  207. package/src/devserver/email/config.ts +0 -141
  208. package/src/devserver/email/console.ts +0 -348
  209. package/src/devserver/email/index.ts +0 -155
  210. package/src/devserver/email/providers.ts +0 -131
  211. package/src/devserver/email/status.ts +0 -23
  212. package/src/devserver/email/validate.ts +0 -37
  213. package/src/devserver/email/wire.ts +0 -55
  214. package/src/devserver/http/cache.ts +0 -0
  215. package/src/devserver/http/envelope.ts +0 -157
  216. package/src/devserver/http/proxy.ts +0 -172
  217. package/src/devserver/http/runtime.ts +0 -387
  218. package/src/devserver/index.ts +0 -43
  219. package/src/devserver/production-ipc.ts +0 -63
  220. package/src/devserver/production-worker.ts +0 -83
  221. package/src/devserver/production.ts +0 -718
  222. package/src/devserver/runtime/crypto.ts +0 -587
  223. package/src/devserver/runtime/host.ts +0 -427
  224. package/src/devserver/runtime/module.ts +0 -442
  225. package/src/devserver/server.ts +0 -251
  226. package/src/devserver/ssr.ts +0 -208
  227. package/src/devserver/stream/catalog.ts +0 -106
  228. package/src/devserver/stream/host.ts +0 -42
  229. package/src/devserver/stream/index.ts +0 -301
  230. package/src/devserver/stream/manager.ts +0 -167
  231. package/src/devserver/stream/router.ts +0 -101
  232. package/src/devserver/stream/wire.ts +0 -58
  233. package/src/devserver/stream/ws.ts +0 -78
  234. package/src/devserver/wasm/sections.ts +0 -59
  235. package/src/devserver/wasm/surface.ts +0 -115
  236. package/src/io/FastMap.ts +0 -151
  237. package/src/io/FastSet.ts +0 -113
  238. package/src/io/codec.ts +0 -362
  239. package/src/io/index.ts +0 -10
  240. package/src/io/lengths.ts +0 -14
  241. package/src/io/types.ts +0 -19
  242. package/src/logger/index.ts +0 -22
  243. package/src/shared/index.ts +0 -46
  244. package/test/analytics-dev.test.ts +0 -113
  245. package/test/assembly/aspect-shim.ts +0 -33
  246. package/test/assembly/cookie.spec.ts +0 -303
  247. package/test/assembly/example.spec.ts +0 -22
  248. package/test/assembly/ssr.spec.ts +0 -95
  249. package/test/assembly.test.ts +0 -59
  250. package/test/auth-emails.test.ts +0 -118
  251. package/test/built-ssr.test.ts +0 -148
  252. package/test/channel.test.ts +0 -21
  253. package/test/config-host-port.test.ts +0 -59
  254. package/test/configure.test.ts +0 -94
  255. package/test/daemon-build.test.ts +0 -278
  256. package/test/daemon-catalog.test.ts +0 -349
  257. package/test/daemon-emulation.test.ts +0 -256
  258. package/test/db.test.ts +0 -0
  259. package/test/devserver-database.test.ts +0 -1102
  260. package/test/devserver-email.test.ts +0 -306
  261. package/test/devserver-pqauth.test.ts +0 -93
  262. package/test/devserver-secrets.test.ts +0 -63
  263. package/test/devserver.test.ts +0 -259
  264. package/test/doctor.test.ts +0 -298
  265. package/test/dom/Image.test.tsx +0 -144
  266. package/test/dom/Link.test.tsx +0 -67
  267. package/test/dom/NavLink.test.tsx +0 -37
  268. package/test/dom/Script.test.tsx +0 -48
  269. package/test/dom/action.test.tsx +0 -146
  270. package/test/dom/error-overlay.test.tsx +0 -44
  271. package/test/dom/loader.test.tsx +0 -121
  272. package/test/dom/navigation.test.ts +0 -59
  273. package/test/dom/revalidate.test.tsx +0 -38
  274. package/test/dom/route-head.test.tsx +0 -56
  275. package/test/dom/router-loading.test.tsx +0 -44
  276. package/test/dom/scroll.test.ts +0 -56
  277. package/test/dom/slot.test.tsx +0 -131
  278. package/test/dom/use-metadata.test.tsx +0 -58
  279. package/test/dom/view-transitions.test.tsx +0 -53
  280. package/test/dynamic-routing.test.ts +0 -132
  281. package/test/email-console.test.ts +0 -86
  282. package/test/email-preview.test.ts +0 -73
  283. package/test/emails.test.ts +0 -58
  284. package/test/errors.test.ts +0 -21
  285. package/test/example-guestbook.test.ts +0 -123
  286. package/test/features.test.ts +0 -149
  287. package/test/fixtures/bignum-wire/spec.ts +0 -25
  288. package/test/fixtures/daemon-app.ts +0 -65
  289. package/test/fixtures/stream-echo.ts +0 -26
  290. package/test/fixtures/stream-gate.ts +0 -28
  291. package/test/fixtures/stream-trap.ts +0 -18
  292. package/test/fixtures/stream-typed.ts +0 -41
  293. package/test/fonts.test.ts +0 -28
  294. package/test/global-setup.ts +0 -17
  295. package/test/head.test.ts +0 -42
  296. package/test/image-blur.test.ts +0 -50
  297. package/test/io.test.ts +0 -117
  298. package/test/metadata.test.ts +0 -40
  299. package/test/navlink.test.ts +0 -28
  300. package/test/pages.test.ts +0 -105
  301. package/test/placeholder.test.ts +0 -9
  302. package/test/pqauth-e2e.test.ts +0 -216
  303. package/test/pqauth-email.test.ts +0 -801
  304. package/test/prerender.test.ts +0 -116
  305. package/test/prettier-plugin.test.ts +0 -46
  306. package/test/routes.test.ts +0 -76
  307. package/test/rpc-bignum-wire.test.ts +0 -164
  308. package/test/rpc-dispatch.test.ts +0 -132
  309. package/test/rpc-kinds.test.ts +0 -18
  310. package/test/rpc.test.ts +0 -66
  311. package/test/search.test.ts +0 -114
  312. package/test/seo.test.ts +0 -175
  313. package/test/slot-layouts.test.ts +0 -69
  314. package/test/sri.test.ts +0 -129
  315. package/test/ssg.test.ts +0 -36
  316. package/test/ssr-hydration.test.tsx +0 -122
  317. package/test/ssr-render.test.ts +0 -197
  318. package/test/ssr-template.test.tsx +0 -482
  319. package/test/stream-emulation.test.ts +0 -479
  320. package/test/ui.test.ts +0 -40
  321. package/test/update.test.ts +0 -58
  322. package/test/validate.test.ts +0 -42
  323. package/test/version-check.test.ts +0 -130
  324. package/tests/data-parity/generated-parity.ts +0 -99
  325. package/tests/data-parity/parity.ts +0 -80
  326. package/tests/data-parity/spec.ts +0 -46
@@ -1,130 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import {
4
- CHECK_TTL_MS,
5
- compareSemver,
6
- findOutdated,
7
- installCommand,
8
- isCacheFresh,
9
- isOutdated,
10
- parseCheckCache,
11
- } from '../src/cli/version-check';
12
-
13
- describe('compareSemver', () => {
14
- it('orders plain versions', () => {
15
- expect(compareSemver('0.0.31', '0.0.32')).toBeLessThan(0);
16
- expect(compareSemver('0.0.32', '0.0.31')).toBeGreaterThan(0);
17
- expect(compareSemver('0.0.31', '0.0.31')).toBe(0);
18
- expect(compareSemver('0.9.9', '0.10.0')).toBeLessThan(0);
19
- expect(compareSemver('1.0.0', '0.99.99')).toBeGreaterThan(0);
20
- });
21
-
22
- it('treats a prerelease as older than its release', () => {
23
- expect(compareSemver('0.1.0-beta.1', '0.1.0')).toBeLessThan(0);
24
- expect(compareSemver('0.1.0', '0.1.0-beta.1')).toBeGreaterThan(0);
25
- expect(compareSemver('0.1.0-alpha', '0.1.0-beta')).toBeLessThan(0);
26
- });
27
-
28
- it('tolerates a leading v and garbage input', () => {
29
- expect(compareSemver('v1.2.3', '1.2.3')).toBe(0);
30
- expect(compareSemver('garbage', '0.0.0')).toBe(0);
31
- });
32
- });
33
-
34
- describe('isOutdated', () => {
35
- it('is true only when installed is behind latest', () => {
36
- expect(isOutdated('0.0.31', '0.0.32')).toBe(true);
37
- expect(isOutdated('0.0.32', '0.0.32')).toBe(false);
38
- // A local build ahead of the registry must not warn.
39
- expect(isOutdated('0.0.33', '0.0.32')).toBe(false);
40
- });
41
- });
42
-
43
- describe('parseCheckCache', () => {
44
- it('parses a valid cache entry', () => {
45
- expect(parseCheckCache('{"latest":"0.0.32","checkedAt":1000}')).toEqual({
46
- latest: '0.0.32',
47
- checkedAt: 1000,
48
- });
49
- });
50
-
51
- it('keeps a cached failure (latest null) so offline machines back off', () => {
52
- expect(parseCheckCache('{"latest":null,"checkedAt":1000}')).toEqual({
53
- latest: null,
54
- checkedAt: 1000,
55
- });
56
- });
57
-
58
- it('rejects malformed contents', () => {
59
- expect(parseCheckCache('not json')).toBeNull();
60
- expect(parseCheckCache('[]')).toBeNull();
61
- expect(parseCheckCache('{"latest":"0.0.32"}')).toBeNull();
62
- expect(parseCheckCache('{"latest":42,"checkedAt":"soon"}')).toBeNull();
63
- });
64
- });
65
-
66
- describe('isCacheFresh', () => {
67
- const cache = { latest: '0.0.32', checkedAt: 10_000 };
68
-
69
- it('is fresh within the TTL and stale after it', () => {
70
- expect(isCacheFresh(cache, 10_000 + CHECK_TTL_MS - 1)).toBe(true);
71
- expect(isCacheFresh(cache, 10_000 + CHECK_TTL_MS)).toBe(false);
72
- });
73
-
74
- it('is stale when the clock went backwards past checkedAt', () => {
75
- expect(isCacheFresh(cache, 9_999)).toBe(false);
76
- });
77
- });
78
-
79
- describe('installCommand', () => {
80
- it('targets the project with the detected package manager', () => {
81
- expect(installCommand('npm', 'project')).toBe('npm install toiljs@latest');
82
- expect(installCommand('pnpm', 'project')).toBe('pnpm add toiljs@latest');
83
- expect(installCommand('yarn', 'project')).toBe('yarn add toiljs@latest');
84
- expect(installCommand('bun', 'project')).toBe('bun add toiljs@latest');
85
- });
86
-
87
- it('targets the global install', () => {
88
- expect(installCommand('npm', 'global')).toBe('npm install -g toiljs@latest');
89
- expect(installCommand('pnpm', 'global')).toBe('pnpm add -g toiljs@latest');
90
- });
91
- });
92
-
93
- describe('findOutdated', () => {
94
- it('flags an outdated project install with the project command', () => {
95
- const rows = findOutdated('0.0.32', '0.0.31', '0.0.31', true, 'pnpm');
96
- expect(rows).toEqual([
97
- { scope: 'project', installed: '0.0.31', command: 'pnpm add toiljs@latest' },
98
- ]);
99
- });
100
-
101
- it('flags an outdated global CLI even when the project is current', () => {
102
- const rows = findOutdated('0.0.32', '0.0.32', '0.0.30', false, 'npm');
103
- expect(rows).toEqual([
104
- { scope: 'global', installed: '0.0.30', command: 'npm install -g toiljs@latest' },
105
- ]);
106
- });
107
-
108
- it('flags both when a stale global CLI runs inside a stale project', () => {
109
- const rows = findOutdated('0.0.32', '0.0.31', '0.0.30', false, 'npm');
110
- expect(rows.map((r) => r.scope)).toEqual(['project', 'global']);
111
- });
112
-
113
- it('does not double-report when the running CLI is the project install', () => {
114
- const rows = findOutdated('0.0.32', '0.0.31', '0.0.31', true, 'npm');
115
- expect(rows).toHaveLength(1);
116
- expect(rows[0].scope).toBe('project');
117
- });
118
-
119
- it('reports nothing when everything is current or ahead', () => {
120
- expect(findOutdated('0.0.32', '0.0.32', '0.0.32', true, 'npm')).toEqual([]);
121
- expect(findOutdated('0.0.32', null, '0.0.33', false, 'npm')).toEqual([]);
122
- });
123
-
124
- it('handles a missing project install (npx outside a project)', () => {
125
- const rows = findOutdated('0.0.32', null, '0.0.31', false, 'npm');
126
- expect(rows).toEqual([
127
- { scope: 'global', installed: '0.0.31', command: 'npm install -g toiljs@latest' },
128
- ]);
129
- });
130
- });
@@ -1,99 +0,0 @@
1
- // Proves the fork's GENERATED @data class (from --rpcModule) matches the AS @data
2
- // wire byte-for-byte. Compiles spec.ts (which has `@data class Foo`) with the
3
- // ToilScript fork, emitting both the wasm and the generated server.ts, then checks
4
- // the generated Foo class against the AS Foo.encode() bytes, both directions.
5
- // Run with: node tests/data-parity/generated-parity.ts
6
- import { readFileSync, writeFileSync, mkdtempSync, rmSync } from "node:fs";
7
- import { tmpdir } from "node:os";
8
- import { join, dirname } from "node:path";
9
- import { fileURLToPath, pathToFileURL } from "node:url";
10
- import { spawnSync } from "node:child_process";
11
- const here = dirname(fileURLToPath(import.meta.url));
12
- // The generated module imports DataWriter/DataReader from this specifier.
13
- const codec = join(here, "..", "..", "src", "io", "codec.ts");
14
- const fork = "/root/toil-stuff/toilscript";
15
- const spec = join(here, "spec.ts");
16
- const tmp = mkdtempSync(join(tmpdir(), "gen-parity-"));
17
- const wasmPath = join(tmp, "spec.wasm");
18
- const modPath = join(tmp, "server.ts");
19
- writeFileSync(join(tmp, "package.json"), '{ "type": "module" }\n');
20
-
21
- const compile = spawnSync(
22
- "node",
23
- [join(fork, "bin", "toilscript.js"), spec, "-o", wasmPath, "--runtime", "stub", "--initialMemory", "32", "--rpcModule", modPath, "--rpcRuntime", codec],
24
- { stdio: "inherit" },
25
- );
26
- if (compile.status !== 0) {
27
- console.error("generated parity: COMPILE FAILED");
28
- rmSync(tmp, { recursive: true, force: true });
29
- process.exit(1);
30
- }
31
-
32
- function fail(msg: string): never {
33
- console.error("generated parity: FAIL,", msg);
34
- rmSync(tmp, { recursive: true, force: true });
35
- process.exit(1);
36
- }
37
- function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {
38
- if (a.length !== b.length) return false;
39
- for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
40
- return true;
41
- }
42
- const hex = (b: Uint8Array): string => Buffer.from(b).toString("hex");
43
-
44
- // the known sample (must match spec.ts `sample()`)
45
- const ID = 0xcafebabedeadbeefn;
46
- const COUNT = -42;
47
- const FLAG = true;
48
- const BIG = 123456789n;
49
- const NAME = "cross-lang";
50
-
51
- // AS side: instantiate and read the sample bytes out of linear memory.
52
- const { instance } = await WebAssembly.instantiate(readFileSync(wasmPath), {
53
- env: { abort: (_m: number, _f: number, line: number) => { throw new Error("wasm abort @ line " + line); } },
54
- });
55
- const x = instance.exports as Record<string, CallableFunction> & { memory: WebAssembly.Memory };
56
- const SCRATCH = 0x100000;
57
- const len = x.encodeSampleTo(SCRATCH) as number;
58
- const wasmBytes = new Uint8Array(x.memory.buffer, SCRATCH, len).slice();
59
-
60
- // Generated side: build the same value with the generated Foo class and encode.
61
- const gen = (await import(pathToFileURL(modPath).href)) as {
62
- Foo: new () => {
63
- id: bigint; count: number; flag: boolean; big: bigint; name: string;
64
- encode(): Uint8Array;
65
- } & Record<string, unknown>;
66
- };
67
- const FooClass = gen.Foo as unknown as {
68
- new (): { id: bigint; count: number; flag: boolean; big: bigint; name: string; encode(): Uint8Array };
69
- decode(buf: Uint8Array): { id: bigint; count: number; flag: boolean; big: bigint; name: string };
70
- dataId(): number;
71
- };
72
-
73
- const foo = new FooClass();
74
- foo.id = ID;
75
- foo.count = COUNT;
76
- foo.flag = FLAG;
77
- foo.big = BIG;
78
- foo.name = NAME;
79
- const genBytes = foo.encode();
80
-
81
- // 1) byte-for-byte identical to the AS @data encoding.
82
- if (!bytesEqual(genBytes, wasmBytes)) {
83
- fail(`byte mismatch\n AS: ${hex(wasmBytes)}\n generated: ${hex(genBytes)}`);
84
- }
85
-
86
- // 2) the generated decode round-trips the AS bytes back to the sample.
87
- const back = FooClass.decode(wasmBytes);
88
- if (back.id !== ID) fail("id (decode)");
89
- if (back.count !== COUNT) fail("count (decode)");
90
- if (back.flag !== FLAG) fail("flag (decode)");
91
- if (back.big !== BIG) fail("big (decode)");
92
- if (back.name !== NAME) fail("name (decode)");
93
-
94
- // 3) the AS side accepts the generated bytes.
95
- new Uint8Array(x.memory.buffer, SCRATCH, genBytes.length).set(genBytes);
96
- if ((x.checkBytes(SCRATCH, genBytes.length) as number) !== 1) fail("AS rejected generated bytes");
97
-
98
- console.log(`@data generated-class parity: PASS (generated <-> AS both ways, byte-for-byte, ${len} bytes)`);
99
- rmSync(tmp, { recursive: true, force: true });
@@ -1,80 +0,0 @@
1
- // Cross-language @data byte-parity proof. Compiles spec.ts with the ToilScript
2
- // fork (which has @data), then checks the TS codec (src/io/codec.ts) against it
3
- // both directions, including byte-for-byte. Run with: node tests/data-parity/parity.ts
4
- import { readFileSync, mkdtempSync, rmSync } from "node:fs";
5
- import { tmpdir } from "node:os";
6
- import { join, dirname } from "node:path";
7
- import { fileURLToPath } from "node:url";
8
- import { spawnSync } from "node:child_process";
9
- import { DataWriter, DataReader } from "../../src/io/codec.ts";
10
-
11
- const here = dirname(fileURLToPath(import.meta.url));
12
- const fork = "/root/toil-stuff/toilscript";
13
- const spec = join(here, "spec.ts");
14
- const tmp = mkdtempSync(join(tmpdir(), "parity-"));
15
- const wasmPath = join(tmp, "spec.wasm");
16
-
17
- const compile = spawnSync(
18
- "node",
19
- [join(fork, "bin", "toilscript.js"), spec, "-o", wasmPath, "--runtime", "stub", "--initialMemory", "32"],
20
- { stdio: "inherit" },
21
- );
22
- if (compile.status !== 0) {
23
- console.error("@data parity: COMPILE FAILED");
24
- rmSync(tmp, { recursive: true, force: true });
25
- process.exit(1);
26
- }
27
-
28
- function fail(msg: string): never {
29
- console.error("@data parity: FAIL,", msg);
30
- rmSync(tmp, { recursive: true, force: true });
31
- process.exit(1);
32
- }
33
- function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {
34
- if (a.length !== b.length) return false;
35
- for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
36
- return true;
37
- }
38
- const hex = (b: Uint8Array): string => Buffer.from(b).toString("hex");
39
-
40
- const { instance } = await WebAssembly.instantiate(readFileSync(wasmPath), {
41
- env: { abort: (_m: number, _f: number, line: number) => { throw new Error("wasm abort @ line " + line); } },
42
- });
43
- const x = instance.exports as Record<string, CallableFunction> & { memory: WebAssembly.Memory };
44
- const mem = x.memory;
45
- const SCRATCH = 0x100000; // 1 MiB, above the low heap
46
-
47
- // the known sample (must match spec.ts)
48
- const ID = 0xcafebabedeadbeefn;
49
- const COUNT = -42;
50
- const FLAG = true;
51
- const BIG = 123456789n;
52
- const NAME = "cross-lang";
53
- const fooId = (x.fooId() as number) >>> 0;
54
-
55
- // 1) ToilScript encodes the sample; read its bytes out of linear memory.
56
- const len = x.encodeSampleTo(SCRATCH) as number;
57
- const wasmBytes = new Uint8Array(mem.buffer, SCRATCH, len).slice();
58
-
59
- // 2) TS decodes the ToilScript bytes.
60
- const r = new DataReader(wasmBytes);
61
- if ((r.readU32() >>> 0) !== fooId) fail("typeId mismatch");
62
- if (r.readU64() !== ID) fail("id (ToilScript -> TS)");
63
- if (r.readI32() !== COUNT) fail("count (ToilScript -> TS)");
64
- if (r.readBool() !== FLAG) fail("flag (ToilScript -> TS)");
65
- if (r.readU128() !== BIG) fail("big (ToilScript -> TS)");
66
- if (r.readString() !== NAME) fail("name (ToilScript -> TS)");
67
- if (!r.ok || r.remaining() !== 0) fail("trailing/ok (ToilScript -> TS)");
68
-
69
- // 3) TS encodes the same value; it must be byte-for-byte identical.
70
- const w = new DataWriter();
71
- w.writeU32(fooId).writeU64(ID).writeI32(COUNT).writeBool(FLAG).writeU128(BIG).writeString(NAME);
72
- const tsBytes = w.toBytes();
73
- if (!bytesEqual(tsBytes, wasmBytes)) fail(`byte mismatch\n ToilScript: ${hex(wasmBytes)}\n TS: ${hex(tsBytes)}`);
74
-
75
- // 4) ToilScript decodes the TS bytes and confirms the value.
76
- new Uint8Array(mem.buffer, SCRATCH, tsBytes.length).set(tsBytes);
77
- if ((x.checkBytes(SCRATCH, tsBytes.length) as number) !== 1) fail("ToilScript rejected TS bytes (TS -> ToilScript)");
78
-
79
- console.log(`@data parity: PASS (ToilScript<->TS both ways, byte-for-byte, ${len} bytes)`);
80
- rmSync(tmp, { recursive: true, force: true });
@@ -1,46 +0,0 @@
1
- // ToilScript side of the cross-language @data parity proof. Compiled by the
2
- // ToilScript fork (which has @data + std/assembly/data.ts). Exposes a known sample so the
3
- // TS codec can be checked against it byte-for-byte, both directions.
4
- //
5
- // A fixed scratch region (high in linear memory, away from the low heap) is used
6
- // to move bytes across the JS boundary without the loader.
7
-
8
- @data
9
- class Foo {
10
- id: u64 = 0;
11
- count: i32 = 0;
12
- flag: bool = false;
13
- big: u128 = u128.Zero;
14
- name: string = "";
15
- }
16
-
17
- function sample(): Foo {
18
- const f = new Foo();
19
- f.id = 0xCAFEBABEDEADBEEF;
20
- f.count = -42;
21
- f.flag = true;
22
- f.big = u128.fromU64(123456789);
23
- f.name = "cross-lang";
24
- return f;
25
- }
26
-
27
- export function fooId(): u32 {
28
- return Foo.dataId();
29
- }
30
-
31
- /** Encode the sample, copy it to `out`, return the byte length. */
32
- export function encodeSampleTo(out: usize): i32 {
33
- const bytes = sample().encode();
34
- memory.copy(out, bytes.dataStart, <usize>bytes.length);
35
- return bytes.length;
36
- }
37
-
38
- /** Decode `len` bytes at `inp` and return 1 if they equal the sample, else 0. */
39
- export function checkBytes(inp: usize, len: i32): i32 {
40
- const bytes = new Uint8Array(len);
41
- memory.copy(bytes.dataStart, inp, <usize>len);
42
- const f = Foo.decode(bytes);
43
- const s = sample();
44
- const ok = f.id == s.id && f.count == s.count && f.flag == s.flag && f.big == s.big && f.name == s.name;
45
- return ok ? 1 : 0;
46
- }