@potentiajs/core 0.1.0-preview.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +441 -0
  4. package/bin/potentia.js +14 -0
  5. package/examples/file-routing-basic/README.md +156 -0
  6. package/examples/file-routing-basic/app.js +16 -0
  7. package/examples/file-routing-basic/generate.js +21 -0
  8. package/examples/file-routing-basic/routes/health.js +3 -0
  9. package/examples/file-routing-basic/routes/index.js +3 -0
  10. package/examples/file-routing-basic/routes/users/[id].js +6 -0
  11. package/examples/file-routing-basic/routes/users/_routes.js +15 -0
  12. package/examples/form-rendering-basic/README.md +43 -0
  13. package/examples/form-rendering-basic/index.js +120 -0
  14. package/examples/full-flow-basic/README.md +141 -0
  15. package/examples/full-flow-basic/app.js +16 -0
  16. package/examples/full-flow-basic/form.js +205 -0
  17. package/examples/full-flow-basic/generate.js +21 -0
  18. package/examples/full-flow-basic/routes/index.js +5 -0
  19. package/examples/full-flow-basic/routes/users/[id].js +5 -0
  20. package/examples/full-flow-basic/routes/users/_routes.js +8 -0
  21. package/examples/full-flow-basic/routes/users/index.js +5 -0
  22. package/examples/full-flow-basic/routes/users/new.js +5 -0
  23. package/package.json +90 -0
  24. package/src/cli.js +407 -0
  25. package/src/dev/file-routing/diagnostics.js +24 -0
  26. package/src/dev/file-routing/generator.js +126 -0
  27. package/src/dev/file-routing/index.js +5 -0
  28. package/src/dev/file-routing/path-mapping.js +125 -0
  29. package/src/dev/file-routing/scanner.js +154 -0
  30. package/src/dev/file-routing/writer.js +100 -0
  31. package/src/file-routing.d.ts +36 -0
  32. package/src/file-routing.js +1 -0
  33. package/src/forms.d.ts +9 -0
  34. package/src/forms.js +334 -0
  35. package/src/index.d.ts +185 -0
  36. package/src/index.js +15 -0
  37. package/src/index.mjs +25 -0
  38. package/src/kernel/action-projection.js +35 -0
  39. package/src/kernel/action.js +172 -0
  40. package/src/kernel/app.js +144 -0
  41. package/src/kernel/context.js +37 -0
  42. package/src/kernel/contract-projection.js +129 -0
  43. package/src/kernel/contract.js +135 -0
  44. package/src/kernel/diagnostics.js +147 -0
  45. package/src/kernel/effect.js +119 -0
  46. package/src/kernel/error.js +93 -0
  47. package/src/kernel/form-projection.js +251 -0
  48. package/src/kernel/form-state.js +173 -0
  49. package/src/kernel/plugin.js +46 -0
  50. package/src/kernel/response.js +187 -0
  51. package/src/kernel/result.js +45 -0
  52. package/src/kernel/route-collection.js +148 -0
  53. package/src/kernel/route-id.js +11 -0
  54. package/src/kernel/route-manifest.js +129 -0
  55. package/src/kernel/route-projection.js +139 -0
  56. package/src/kernel/route.js +156 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0-preview.0
4
+
5
+ Experimental public preview for `@potentiajs/core`.
6
+
7
+ PotentiaJS is still not production-ready and has no stable public API commitment. All root exports remain experimental and may change before a stable release.
8
+
9
+ ### Highlights
10
+
11
+ - Added a Bun-first routing kernel for explicit, contract-driven request handling.
12
+ - Added explicit route composition with route collections and mounts.
13
+ - Added SigilJS request, response, and action contract boundaries.
14
+ - Added experimental effect descriptors and helpers.
15
+ - Added experimental actions with JSON input and URL-encoded form-compatible action input.
16
+ - Added normalized diagnostics for route/action validation failures.
17
+ - Added safe form state helper for failed form submissions.
18
+ - Added renderer-independent form projection metadata.
19
+ - Added route, action, manifest, and contract projection metadata.
20
+ - Added focused examples for kernel, SigilJS, composition, actions, and form state.
21
+ - Pruned root exports to the intentional public preview surface.
22
+
23
+ ### Not included
24
+
25
+ - Stable API commitment.
26
+ - Production-readiness claim.
27
+ - Frontend runtime.
28
+ - Renderer or form generator.
29
+ - Client SDK.
30
+ - OpenAPI generator.
31
+ - Multipart/file upload helpers.
32
+ - Session/flash helpers.
33
+ - TypeScript source conversion.
34
+ - Public file-routing API.
35
+ - Package split.
36
+ - DB/auth integrations.
37
+
38
+ ### Notes
39
+
40
+ - Runtime target: Bun.
41
+ - Source remains plain JavaScript ES modules.
42
+ - Runtime dependency: `@weipertda/sigiljs@0.18.0`.
43
+ - Minimal TypeScript declarations are included for editor/type discovery, but they are conservative and experimental.
44
+ - Post-release verification should confirm the registry artifact users receive.
45
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Weipert
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,441 @@
1
+ # PotentiaJS
2
+
3
+ PotentiaJS is an experimental Bun-first JavaScript framework kernel for explicit, contract-driven request handling.
4
+
5
+ It is **not production-ready** and has **no stable public API** yet.
6
+
7
+ ## Current status
8
+
9
+ - Package: `@potentiajs/core`
10
+ - Version: `0.1.0-preview.0`
11
+ - Visibility: public preview package candidate
12
+ - License: MIT
13
+ - Runtime: Bun
14
+ - Source: plain JavaScript ES modules
15
+ - TypeScript source: none
16
+ - Runtime dependency: `@weipertda/sigiljs@0.18.0`
17
+ - Type declarations: minimal conservative declarations included
18
+
19
+ Current kernel flow:
20
+
21
+ ```txt
22
+ Request → Route Match → Contract Boundary → Effect Execution → Result Normalization → Response
23
+ ```
24
+
25
+ ## Install / local usage
26
+
27
+ Once registry visibility is confirmed, the preview package install shape is:
28
+
29
+ ```bash
30
+ bun add @potentiajs/core
31
+ ```
32
+
33
+ From this repository:
34
+
35
+ ```bash
36
+ bun install
37
+ bun run test
38
+ bun run check
39
+ bun run check:preview
40
+ ```
41
+
42
+ If the registry install command fails, check the post-release verification notes: the registry artifact may not be visible yet even though release metadata is prepared.
43
+
44
+ ## Minimal route
45
+
46
+ ```js
47
+ import { createApp, json, ok, route } from '@potentiajs/core';
48
+
49
+ const app = createApp({
50
+ routes: [
51
+ route('GET', '/', () => ok(json({ ok: true })))
52
+ ]
53
+ });
54
+
55
+ Bun.serve({ fetch: app.fetch });
56
+ ```
57
+
58
+ ## SigilJS contract route
59
+
60
+ Potentia uses SigilJS for runtime contracts.
61
+
62
+ ```js
63
+ import { sigil, optional } from '@weipertda/sigiljs';
64
+ import { createApp, json, ok, route } from '@potentiajs/core';
65
+
66
+ const UserParams = sigil({ id: String });
67
+ const UserQuery = sigil({ include: optional(String) });
68
+ const UserResponse = sigil({ id: String, name: String });
69
+
70
+ const app = createApp({
71
+ routes: [
72
+ route('GET', '/users/:id', (ctx) => ok(json({
73
+ id: ctx.params.id,
74
+ name: ctx.query.include === 'full' ? 'Ada Lovelace' : 'Ada'
75
+ })), {
76
+ params: UserParams,
77
+ query: UserQuery,
78
+ response: UserResponse
79
+ })
80
+ ]
81
+ });
82
+ ```
83
+
84
+ SigilJS `0.18.0` uses JavaScript constructors/helpers such as `sigil({ id: String })` and `optional(String)`.
85
+
86
+ ## Route composition
87
+
88
+ Composition is explicit. File routing is optional generated projection, not auto-discovery during request handling or a global mutable route registry.
89
+
90
+ ```js
91
+ import { createApp, createRoutes, json, mount, ok, route } from '@potentiajs/core';
92
+
93
+ const userRoutes = createRoutes({
94
+ prefix: '/users',
95
+ routes: [
96
+ route('GET', '/', () => ok(json({ users: [] }))),
97
+ route('GET', '/:id', (ctx) => ok(json({ id: ctx.params.id })))
98
+ ]
99
+ });
100
+
101
+ const app = createApp({
102
+ routes: [
103
+ route('GET', '/', () => ok(json({ ok: true }))),
104
+ mount(userRoutes, { prefix: '/api' })
105
+ ]
106
+ });
107
+ ```
108
+
109
+ Effective paths:
110
+
111
+ - `/`
112
+ - `/api/users`
113
+ - `/api/users/:id`
114
+
115
+ The experimental file-routing subpath follows this explicit model:
116
+
117
+ ```txt
118
+ filesystem → route modules → createRoutes / route / mount → createApp
119
+ ```
120
+
121
+ The file-routing preview API can scan a route tree and generate an explicit `.potentia/routes.generated.js` module. It is a package subpath, not a root export.
122
+
123
+ Route files:
124
+
125
+ ```txt
126
+ routes/
127
+ index.js
128
+ health.js
129
+ users/
130
+ [id].js
131
+ ```
132
+
133
+ Generate explicit routes with the experimental CLI:
134
+
135
+ ```bash
136
+ potentia routes generate
137
+ potentia routes check
138
+ ```
139
+
140
+ Equivalent explicit form:
141
+
142
+ ```bash
143
+ potentia routes generate --root routes --out .potentia/routes.generated.js --package @potentiajs/core
144
+ potentia routes check --root routes --out .potentia/routes.generated.js --package @potentiajs/core
145
+ ```
146
+
147
+ `generate` writes `.potentia/routes.generated.js`. `check` verifies the generated output is current without writing files, which makes it suitable for CI. Both commands support the same `--root`, `--out`, `--package`, and `--cwd` flags.
148
+
149
+ For scripts and CI tooling, add `--json` to either command:
150
+
151
+ ```bash
152
+ potentia routes generate --json
153
+ potentia routes check --json
154
+ ```
155
+
156
+ JSON changes output format only: `generate --json` still writes files, `check --json` remains non-mutating, JSON envelopes go to stdout, and exit codes remain the same. The CLI does not include watch mode, config files, a dev server, or a compiler.
157
+
158
+ You can also call the programmatic API directly:
159
+
160
+ ```js
161
+ import { generateFileRoutes } from '@potentiajs/core/file-routing';
162
+
163
+ await generateFileRoutes({
164
+ rootDir: 'routes',
165
+ outputFile: '.potentia/routes.generated.js'
166
+ });
167
+ ```
168
+
169
+ Use the generated module explicitly:
170
+
171
+ ```js
172
+ import { createApp } from '@potentiajs/core';
173
+ import routes from './.potentia/routes.generated.js';
174
+
175
+ const app = createApp({
176
+ routes: [routes]
177
+ });
178
+ ```
179
+
180
+ File routing remains projection over explicit route composition: generated modules import `createRoutes(...)` / `mount(...)` from `@potentiajs/core`, while runtime apps still consume normal route collections. The generated `.potentia/` directory is ignored by default and is usually not committed. The runtime kernel does not perform production runtime filesystem scanning. Watch mode, config files, dev server behavior, and compiler integration remain deferred.
181
+
182
+ See [`examples/file-routing-basic/`](examples/file-routing-basic/) for a runnable example.
183
+
184
+ See [`examples/full-flow-basic/`](examples/full-flow-basic/) for a compact full-flow app combining file routing, actions, form projection, server-rendered forms, form state, and redirects.
185
+
186
+ ## Effects
187
+
188
+ Handlers and hooks may be plain functions, async functions, or experimental `effect(...)` descriptors. Effect helpers are small command constructors that keep generator workflows readable.
189
+
190
+ ```js
191
+ import { call, effect, json, ok, route } from '@potentiajs/core';
192
+
193
+ const loadGreeting = (name) => ({ message: `hello ${name}` });
194
+
195
+ route('GET', '/hello', effect(function* hello(ctx) {
196
+ const greeting = yield call(loadGreeting, ctx.query.name || 'world');
197
+ return ok(json(greeting));
198
+ }));
199
+ ```
200
+
201
+ Available helpers are `call(fn, ...args)`, `value(value)`, and `context(key)`. Raw command objects remain supported for compatibility, but helpers are preferred for normal usage.
202
+
203
+ The current effect runner is intentionally small. It is not a full effect system: concurrency, retries, cancellation, timeouts, queues, supervisors, and workflow tracing are deferred.
204
+
205
+ ## Contract projection
206
+
207
+ Projection APIs are experimental metadata helpers for docs, tests, examples, and future tooling. They do not execute handlers, hooks, or generic contract logic.
208
+
209
+ ```js
210
+ import { createRouteManifest, projectContract, projectRoute, projectRoutes } from '@potentiajs/core';
211
+
212
+ const contract = projectContract(UserResponse);
213
+ const single = projectRoute(route('GET', '/users/:id', handler, { response: UserResponse }));
214
+ const collection = projectRoutes(app);
215
+ const manifest = createRouteManifest(app, { packageName: '@potentiajs/core', packageVersion: '0.1.0-preview.0' });
216
+ ```
217
+
218
+ `projectContract()` reports honest metadata such as capability, opacity, schema, field summaries, required fields, and optional fields. Generic function/parse/check contracts remain opaque. SigilJS contracts expose richer metadata only where SigilJS safely provides it.
219
+
220
+ `projectRoute()` and `projectRoutes()` summarize methods, paths, contract boundaries, and hook counts without running application code. These helpers are not OpenAPI, client, forms, or docs generators; those remain deferred.
221
+
222
+ Route metadata is experimental. Routes may include optional `name`, `meta`, and `source` options for manifest/tooling descriptions. `createRouteManifest()` creates a deterministic route manifest with route IDs, names, contracts, hook counts, source/meta, diagnostics, and lookup tables. Manifest creation does not execute handlers, hooks, or contracts; it is a foundation for future docs, tests, clients, forms/actions, and dev tooling, not a completed generator.
223
+
224
+ ## Actions
225
+
226
+ Actions are experimental server-side contract boundaries. They support JSON input and `application/x-www-form-urlencoded` input. Parsed and validated action input is attached to `ctx.input`, handlers may use plain/async/effect execution, and output contracts validate the logical response body before route response projection.
227
+
228
+ ```js
229
+ import { action, call, effect, json, ok, route } from '@potentiajs/core';
230
+
231
+ const createUser = action('users.create', effect(function* createUser(ctx) {
232
+ const user = yield call(insertUser, ctx.input);
233
+ return ok(json(user));
234
+ }), {
235
+ input: CreateUserInput,
236
+ output: CreateUserOutput
237
+ });
238
+
239
+ route('POST', '/users', createUser);
240
+ ```
241
+
242
+ URL-encoded submissions parse into plain objects. Repeated fields become arrays, empty values stay empty strings, and values remain strings until input contracts transform them.
243
+
244
+ Actions return normal Potentia results and responses. Use `ok(...)` for success, `fail(...)` for intentional domain failures, and `redirect(...)` for explicit post-action redirects. Validation failures are deterministic and safe: action input failures return `ok: false`, an action error code, boundary metadata, and an issues array.
245
+
246
+ Server validation remains authoritative. Form generation, multipart/file uploads, frontend runtime, client SDK, and OpenAPI generation remain deferred. Future client-side validation will be projection-only convenience.
247
+
248
+ `createFormState(...)` is an experimental opt-in helper for failed form submissions. It preserves safe parsed values only, omits sensitive fields such as passwords/tokens/secrets, groups canonical issues by field with `_form` for root-level issues, and leaves default action behavior unchanged. Redirects remain explicit; successful form submissions should use `redirect('/path', 303)` when post-submit navigation is desired.
249
+
250
+ ```js
251
+ return fail(createFormState({
252
+ ok: false,
253
+ values: ctx.input,
254
+ error: { code: 'USER_EMAIL_TAKEN', message: 'Email is already in use' }
255
+ }), 409);
256
+ ```
257
+
258
+ Potentia also includes an experimental optional server-side HTML string renderer on the forms subpath. Rendering is metadata-driven, escaped by default, and state-aware. It does not add a frontend runtime, JSX, hydration, custom renderer system, client SDK, OpenAPI generator, session/flash helper, or multipart/file upload helper.
259
+
260
+ ```js
261
+ import { createFormState, projectForm } from '@potentiajs/core';
262
+ import { renderForm } from '@potentiajs/core/forms';
263
+
264
+ const formProjection = projectForm(createUser);
265
+ const formState = createFormState({
266
+ ok: false,
267
+ values: ctx.input,
268
+ error: { code: 'USER_EMAIL_TAKEN', message: 'Email is already in use' }
269
+ });
270
+
271
+ const html = renderForm(formProjection, {
272
+ action: '/users',
273
+ state: formState
274
+ });
275
+ ```
276
+
277
+ `renderForm(...)` returns a plain HTML string. It renders projected fields, preserves safe state values, omits sensitive values, and renders root/field errors. It supports explicit textarea and hidden metadata, finite options as `<select>`, stable `data-potentia-*` styling/testing hooks, and baseline accessibility attributes. Server validation remains authoritative. The renderer is intentionally exported from `@potentiajs/core/forms`, not the package root.
278
+
279
+ `projectForm(...)` is an experimental metadata-only helper. It projects action input contracts into renderer-independent field metadata where safe. SigilJS object contracts can expose field paths, derived labels, conservative input hints, required/optional flags, scalar-array `multiple` hints, and sensitive flags. Generic function/parse/check contracts remain opaque and do not invent fields. Server validation remains authoritative.
280
+
281
+ ## Hooks
282
+
283
+ Apps, route collections, and mounts can define lifecycle hooks:
284
+
285
+ ```js
286
+ const secureRoutes = createRoutes({
287
+ hooks: {
288
+ beforeRequest: [requireAuth],
289
+ afterResponse: [auditResponse],
290
+ onError: [recover]
291
+ },
292
+ routes: []
293
+ });
294
+ ```
295
+
296
+ Hook order for matched routes:
297
+
298
+ 1. app `beforeRequest`
299
+ 2. outer collection `beforeRequest`
300
+ 3. inner collection `beforeRequest`
301
+ 4. route handler
302
+ 5. inner collection `afterResponse`
303
+ 6. outer collection `afterResponse`
304
+ 7. app `afterResponse`
305
+
306
+ Scoped `onError` recovery is nearest-local first, then outer scopes, then app hooks.
307
+
308
+ ## Error/result model
309
+
310
+ Handlers usually return `ok(value)` or `fail(error)`. Response helpers create descriptors that project to native `Response` objects:
311
+
312
+ ```js
313
+ return ok(json({ ok: true }));
314
+ ```
315
+
316
+ Safe contract failure body example:
317
+
318
+ ```js
319
+ {
320
+ ok: false,
321
+ error: {
322
+ code: 'POTENTIA_CONTRACT_FAILED',
323
+ message: 'Request body failed contract validation',
324
+ boundary: 'body',
325
+ issues: [{
326
+ code: 'invalid_type',
327
+ message: 'SigilJS contract rejected value',
328
+ path: ['email'],
329
+ field: 'email',
330
+ boundary: 'body',
331
+ source: 'sigil',
332
+ expected: 'string',
333
+ received: 'number',
334
+ meta: null
335
+ }]
336
+ },
337
+ boundary: 'body',
338
+ issues: [/* same issue objects */]
339
+ }
340
+ ```
341
+
342
+ Contract failures now expose normalized issue metadata across route and action boundaries. SigilJS can provide field-level `path` / `field` issues where structured metadata is available. Generic contracts remain opaque and use root-level issues (`path: []`, `field: null`). Raw input values are not exposed; `received` uses safe type descriptors such as `string`, `number`, `array`, or `object`. These diagnostics support future forms/tooling, but Potentia still does not include a form generator, client SDK, or OpenAPI generator.
343
+
344
+ Unsafe thrown handler errors return `POTENTIA_HANDLER_FAILED` with `Internal server error`.
345
+
346
+ ## Examples
347
+
348
+ - [`examples/kernel-basic/`](examples/kernel-basic/) — generic contract kernel smoke app.
349
+ - [`examples/sigiljs-basic/`](examples/sigiljs-basic/) — focused SigilJS contract smoke app.
350
+ - [`examples/composed-basic/`](examples/composed-basic/) — explicit route composition smoke app.
351
+ - [`examples/action-basic/`](examples/action-basic/) — experimental JSON and URL-encoded action smoke app.
352
+ - [`examples/form-state-basic/`](examples/form-state-basic/) — opt-in safe form state helper smoke app.
353
+ - [`examples/form-rendering-basic/`](examples/form-rendering-basic/) — server-rendered escaped form HTML smoke app.
354
+ - [`examples/file-routing-basic/`](examples/file-routing-basic/) — experimental file-route generation smoke app.
355
+ - [`examples/full-flow-basic/`](examples/full-flow-basic/) — file routing + actions + form projection + server-rendered forms.
356
+
357
+ Each example exports `app` for smoke tests and only starts `Bun.serve()` when run directly.
358
+
359
+ ## Commands
360
+
361
+ ```bash
362
+ bun run test # test suite
363
+ bun run check # current local check
364
+ bun run check:preview # tests + check + npm pack dry-run
365
+ bun run check:release # preview release check alias
366
+ bun run check:file-routing # internal file-routing projection tests
367
+ potentia routes generate # experimental file-route generation CLI after package install/link
368
+ potentia routes check # verify generated file-route output is current without writing
369
+ bun run generate:file-routes -- --root routes --out .potentia/routes.generated.js # internal/dev-only generation wrapper
370
+ bun run pack:dry # npm pack --dry-run --json
371
+ ```
372
+
373
+ ## Current limitations
374
+
375
+ Deferred intentionally:
376
+
377
+ - stable public APIs
378
+ - registry visibility may lag or require release verification
379
+ - stable public file-based routing API and route auto-discovery beyond the experimental `@potentiajs/core/file-routing` generation subpath
380
+ - nested layout routing
381
+ - frontend rendering and hydration
382
+ - client router
383
+ - stable server actions/RPC
384
+ - full middleware ecosystem
385
+ - large plugin ecosystem
386
+ - async plugin loading/discovery
387
+ - advanced effect workflows/concurrency/retries/cancellation
388
+ - field-level verbose contract diagnostics
389
+ - OpenAPI/JSON Schema/route docs/client/forms generators
390
+ - multipart/file uploads and form generation
391
+ - session/flash form state persistence
392
+ - route manifest file writing/loading
393
+ - streaming/file responses/content negotiation/cookies API
394
+ - CLI expansion
395
+ - `.view` compiler changes
396
+ - database integration
397
+ - auth
398
+ - package splitting
399
+ - automatic publish on push
400
+
401
+ ## Public API status
402
+
403
+ All exports are experimental:
404
+
405
+ - app/routes/actions/forms: `createApp`, `route`, `action`, `createFormState`, `createRoutes`, `mount`, `composeRoutes`
406
+ - results/responses: `ok`, `fail`, `json`, `text`, `redirect`
407
+ - effects: `effect`, `call`, `value`, `context`
408
+ - errors: `createFrameworkError`
409
+ - contracts/projection/manifest/plugins: `projectContract`, `projectAction`, `projectForm`, `projectRoute`, `projectRoutes`, `createRouteManifest`, `createPlugin`
410
+
411
+ Lower-level implementation helpers such as request-context construction, effect execution, framework error normalization, and response projection remain internal and may be reshaped before any stable API commitment.
412
+
413
+ Experimental package subpaths:
414
+
415
+ - file routing generation: `@potentiajs/core/file-routing` exports `generateFileRoutes`
416
+
417
+ ## Release / publish status
418
+
419
+ Prepared for public preview dry-run verification:
420
+
421
+ - package metadata targets `@potentiajs/core@0.1.0-preview.0`
422
+ - license is MIT
423
+ - repository metadata targets `https://github.com/antistructured/potentiajs`
424
+ - package is configured as public
425
+ - `CHANGELOG.md` and conservative declarations are included
426
+ - no public API is stable
427
+ - registry visibility is verified during post-release checks
428
+
429
+ Post-release verification should confirm the registry package is visible before sharing install instructions widely.
430
+
431
+ ## License
432
+
433
+ MIT © Daniel Weipert
434
+
435
+ See [`LICENSE`](LICENSE).
436
+
437
+ ## Changelog
438
+
439
+ See [`CHANGELOG.md`](CHANGELOG.md).
440
+
441
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { main } from '../src/cli.js';
4
+
5
+ main(process.argv.slice(2), {
6
+ cwd: process.cwd(),
7
+ stdout: process.stdout,
8
+ stderr: process.stderr
9
+ }).then((code) => {
10
+ process.exitCode = code;
11
+ }).catch((error) => {
12
+ process.stderr.write(`Unexpected Potentia CLI failure: ${error instanceof Error ? error.message : String(error)}\n`);
13
+ process.exitCode = 1;
14
+ });
@@ -0,0 +1,156 @@
1
+ # File Routing Basic Example
2
+
3
+ This example shows PotentiaJS file routing as explicit generated route composition.
4
+
5
+ ```txt
6
+ route files
7
+ → potentia routes generate
8
+ → .potentia/routes.generated.js
9
+ → createApp(...)
10
+ ```
11
+
12
+ File routing is optional and experimental. The CLI is a thin generation wrapper; it is not watch mode, not a dev server, and not runtime request-time filesystem scanning.
13
+
14
+ ## Route tree
15
+
16
+ ```txt
17
+ examples/file-routing-basic/
18
+ generate.js
19
+ app.js
20
+ routes/
21
+ index.js
22
+ health.js
23
+ users/
24
+ _routes.js
25
+ [id].js
26
+ ```
27
+
28
+ Projected routes:
29
+
30
+ - `routes/index.js` → `/`
31
+ - `routes/health.js` → `/health`
32
+ - `routes/users/[id].js` → `/users/:id`
33
+ - `routes/users/_routes.js` → scoped metadata/hooks for the `users` folder
34
+
35
+ ## Generate routes
36
+
37
+ Use the CLI:
38
+
39
+ ```bash
40
+ potentia routes generate \
41
+ --root examples/file-routing-basic/routes \
42
+ --out examples/file-routing-basic/.potentia/routes.generated.js
43
+ ```
44
+
45
+ Verify generated output without writing files:
46
+
47
+ ```bash
48
+ potentia routes check \
49
+ --root examples/file-routing-basic/routes \
50
+ --out examples/file-routing-basic/.potentia/routes.generated.js
51
+ ```
52
+
53
+ `generate` writes the route module. `check` only verifies the generated output is current, making it useful for CI.
54
+
55
+ For scripts and CI tooling, both commands can emit JSON:
56
+
57
+ ```bash
58
+ potentia routes generate --json \
59
+ --root examples/file-routing-basic/routes \
60
+ --out examples/file-routing-basic/.potentia/routes.generated.js
61
+ potentia routes check --json \
62
+ --root examples/file-routing-basic/routes \
63
+ --out examples/file-routing-basic/.potentia/routes.generated.js
64
+ ```
65
+
66
+ JSON changes output format only: `generate --json` still writes files, `check --json` remains non-mutating, JSON envelopes go to stdout, and exit codes remain the same.
67
+
68
+ Or run the programmatic example script:
69
+
70
+ ```bash
71
+ bun examples/file-routing-basic/generate.js
72
+ ```
73
+
74
+ The programmatic script uses the public subpath:
75
+
76
+ ```js
77
+ import { generateFileRoutes } from '@potentiajs/core/file-routing';
78
+
79
+ await generateFileRoutes({
80
+ rootDir: new URL('./routes', import.meta.url).pathname,
81
+ outputFile: new URL('./.potentia/routes.generated.js', import.meta.url).pathname
82
+ });
83
+ ```
84
+
85
+ This writes:
86
+
87
+ ```txt
88
+ examples/file-routing-basic/.potentia/routes.generated.js
89
+ ```
90
+
91
+ The generated file is inspectable JavaScript. It imports route modules and exports an explicit `createRoutes(...)` collection.
92
+
93
+ The start of the file looks like this:
94
+
95
+ ```js
96
+ // Generated by PotentiaJS. Do not edit by hand.
97
+ import { createRoutes, mount } from '@potentiajs/core';
98
+ ```
99
+
100
+ That generated module is normal JavaScript: it imports your route files and composes them. It does not scan the filesystem when a request arrives.
101
+
102
+ ## Use generated routes
103
+
104
+ `app.js` consumes the generated module explicitly:
105
+
106
+ ```js
107
+ import { createApp } from '@potentiajs/core';
108
+ import routes from './.potentia/routes.generated.js';
109
+
110
+ export const app = createApp({
111
+ routes: [routes]
112
+ });
113
+ ```
114
+
115
+ ## Run locally
116
+
117
+ Generate first, then run the app:
118
+
119
+ ```bash
120
+ potentia routes generate \
121
+ --root examples/file-routing-basic/routes \
122
+ --out examples/file-routing-basic/.potentia/routes.generated.js
123
+ potentia routes check \
124
+ --root examples/file-routing-basic/routes \
125
+ --out examples/file-routing-basic/.potentia/routes.generated.js
126
+ bun examples/file-routing-basic/app.js
127
+ ```
128
+
129
+ Try:
130
+
131
+ ```bash
132
+ curl http://localhost:3000/
133
+ curl http://localhost:3000/health
134
+ curl http://localhost:3000/users/ada
135
+ ```
136
+
137
+ ## Generated output policy
138
+
139
+ - `.potentia/routes.generated.js` is generated output.
140
+ - `.potentia/` is ignored by default in this repository.
141
+ - Generation runs during a dev/build step, not during request handling.
142
+ - The generated module must not scan the filesystem at runtime.
143
+ - `potentia routes check` verifies generated output without writing or rewriting files.
144
+ - Add `--json` to `generate` or `check` for machine-readable stdout envelopes; exit codes remain unchanged.
145
+ - Normal app projects usually should not commit `.potentia/`; package authors may choose differently if they intentionally ship generated code.
146
+ - If generation fails, Potentia reports diagnostics and avoids replacing the previous valid output.
147
+
148
+ ## Deferred
149
+
150
+ - watch mode
151
+ - config file support
152
+ - compiler integration
153
+ - dev server
154
+ - TypeScript route files
155
+ - named method exports such as `GET` / `POST`
156
+ - catch-all, optional, and route-group conventions
@@ -0,0 +1,16 @@
1
+ import { createApp } from '@potentiajs/core';
2
+
3
+ import routes from './.potentia/routes.generated.js';
4
+
5
+ export const app = createApp({
6
+ routes: [routes]
7
+ });
8
+
9
+ if (import.meta.main) {
10
+ Bun.serve({
11
+ port: 3000,
12
+ fetch: app.fetch
13
+ });
14
+
15
+ console.log('Potentia file routing example running at http://localhost:3000');
16
+ }