@c9up/aurora 0.1.17 → 0.1.18

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.
@@ -22,6 +22,13 @@ export interface AuroraManagerConfig {
22
22
  * Override only if you want to serve a custom build.
23
23
  */
24
24
  auroraDistRoot?: string;
25
+ /**
26
+ * Filesystem path to `@c9up/comet`'s `dist/`. Defaults to the dist of the
27
+ * installed (optional-peer) `@c9up/comet` — resolved automatically so the
28
+ * RPC client's `import '@c9up/comet'` works in the no-bundler browser with
29
+ * zero app wiring. Left unserved when comet isn't installed (no RPC).
30
+ */
31
+ cometDistRoot?: string;
25
32
  /**
26
33
  * URL prefix the asset routes mount under. The aurora runtime is served
27
34
  * from `<assetsPrefix>/aurora/*` and the app's pages from
@@ -41,6 +48,10 @@ export declare class AuroraManager {
41
48
  readonly auroraAssetPath: string;
42
49
  /** Mount path for the app's pages — `<assetsPrefix>/pages`. */
43
50
  readonly pageAssetPath: string;
51
+ /** Mount path for the RPC client's `@c9up/comet` runtime — `<assetsPrefix>/comet`. */
52
+ readonly cometAssetPath: string;
53
+ /** Resolved `@c9up/comet` dist dir, or `null` when comet isn't installed. */
54
+ readonly cometDistRoot: string | null;
44
55
  constructor(config: AuroraManagerConfig);
45
56
  /**
46
57
  * SSR + hydrate + ship the document. The importmap default points
@@ -59,4 +70,10 @@ export declare class AuroraManager {
59
70
  * `GET /_assets/pages/*`.
60
71
  */
61
72
  pageAssetsHandler(): (ctx: AssetsHttpContext) => Promise<void>;
73
+ /**
74
+ * Handler for `@c9up/comet`'s runtime (the RPC client). Mount on
75
+ * `GET <cometAssetPath>/*`. Returns `null` when comet isn't installed —
76
+ * the provider then skips the route (no RPC, nothing to serve).
77
+ */
78
+ cometAssetsHandler(): ((ctx: AssetsHttpContext) => Promise<void>) | null;
62
79
  }
@@ -15,8 +15,21 @@ import { dirname, resolve as resolvePath } from "node:path";
15
15
  import { fileURLToPath } from "node:url";
16
16
  import { Pages } from "./Pages.js";
17
17
  import { renderPage, } from "./server/renderPage.js";
18
- import { serveAssets } from "./server/serveAssets.js";
18
+ import { packageAssetDir, serveAssets, } from "./server/serveAssets.js";
19
19
  const DEFAULT_AURORA_DIST = resolvePath(dirname(fileURLToPath(import.meta.url)), "../dist");
20
+ /**
21
+ * Resolve `@c9up/comet`'s dist dir, or `null` when it isn't installed. comet is
22
+ * aurora's OPTIONAL peer (only present when the app uses RPC), so a missing one
23
+ * is expected — aurora then simply doesn't serve it or add it to the importmap.
24
+ */
25
+ function resolveCometDist() {
26
+ try {
27
+ return packageAssetDir("@c9up/comet");
28
+ }
29
+ catch {
30
+ return null;
31
+ }
32
+ }
20
33
  /** Normalize an asset prefix: ensure a leading slash, drop trailing slashes. */
21
34
  function normalizePrefix(prefix) {
22
35
  const withLead = prefix.startsWith("/") ? prefix : `/${prefix}`;
@@ -31,10 +44,16 @@ export class AuroraManager {
31
44
  auroraAssetPath;
32
45
  /** Mount path for the app's pages — `<assetsPrefix>/pages`. */
33
46
  pageAssetPath;
47
+ /** Mount path for the RPC client's `@c9up/comet` runtime — `<assetsPrefix>/comet`. */
48
+ cometAssetPath;
49
+ /** Resolved `@c9up/comet` dist dir, or `null` when comet isn't installed. */
50
+ cometDistRoot;
34
51
  constructor(config) {
35
52
  this.assetsPrefix = normalizePrefix(config.assetsPrefix ?? "/_assets");
36
53
  this.auroraAssetPath = `${this.assetsPrefix}/aurora`;
37
54
  this.pageAssetPath = `${this.assetsPrefix}/pages`;
55
+ this.cometAssetPath = `${this.assetsPrefix}/comet`;
56
+ this.cometDistRoot = config.cometDistRoot ?? resolveCometDist();
38
57
  // Pages serve their compiled JS from the same prefix unless the app
39
58
  // pins an explicit urlPrefix.
40
59
  this.pages = new Pages({
@@ -54,6 +73,12 @@ export class AuroraManager {
54
73
  ...options,
55
74
  importmap: {
56
75
  "@c9up/aurora": `${this.auroraAssetPath}/index.js`,
76
+ // Auto-map @c9up/comet when installed so `@c9up/aurora/rpc`'s bare
77
+ // `import '@c9up/comet'` resolves in the no-bundler browser — no
78
+ // app-side importmap wiring. Omitted when comet isn't present.
79
+ ...(this.cometDistRoot
80
+ ? { "@c9up/comet": `${this.cometAssetPath}/index.js` }
81
+ : {}),
57
82
  ...options?.importmap,
58
83
  },
59
84
  });
@@ -72,4 +97,14 @@ export class AuroraManager {
72
97
  pageAssetsHandler() {
73
98
  return serveAssets({ root: this.pages.root });
74
99
  }
100
+ /**
101
+ * Handler for `@c9up/comet`'s runtime (the RPC client). Mount on
102
+ * `GET <cometAssetPath>/*`. Returns `null` when comet isn't installed —
103
+ * the provider then skips the route (no RPC, nothing to serve).
104
+ */
105
+ cometAssetsHandler() {
106
+ return this.cometDistRoot
107
+ ? serveAssets({ root: this.cometDistRoot })
108
+ : null;
109
+ }
75
110
  }
@@ -67,6 +67,13 @@ export default class AuroraProvider {
67
67
  // `/_assets`) — set `config.aurora.assetsPrefix` to change the scheme.
68
68
  router.get(`${manager.auroraAssetPath}/*`, adaptHandler(manager.auroraAssetsHandler()));
69
69
  router.get(`${manager.pageAssetPath}/*`, adaptHandler(manager.pageAssetsHandler()));
70
+ // Serve @c9up/comet's runtime so the RPC client's bare `import
71
+ // '@c9up/comet'` resolves in the browser. Skipped when comet isn't
72
+ // installed (optional peer — the app doesn't use RPC).
73
+ const cometHandler = manager.cometAssetsHandler();
74
+ if (cometHandler) {
75
+ router.get(`${manager.cometAssetPath}/*`, adaptHandler(cometHandler));
76
+ }
70
77
  }
71
78
  async ready() { }
72
79
  async shutdown() { }
@@ -9,6 +9,17 @@
9
9
  * and writes to `ctx.response`. Any context that satisfies
10
10
  * `AssetsHttpContext` (Ream, AdonisJS, anything duck-typed) works.
11
11
  */
12
+ /**
13
+ * Absolute dist directory of an installed package — for mounting its pre-built
14
+ * ESM as browser assets (`serveAssets({ root: packageAssetDir('@c9up/x') })`).
15
+ *
16
+ * Uses `import.meta.resolve`, which honours the package's `exports` `import`
17
+ * condition — so it works for `@c9up/*` import-only packages where
18
+ * `createRequire().resolve()` throws `ERR_PACKAGE_PATH_NOT_EXPORTED` (their
19
+ * `exports` carry no `require` condition, and `main` is ignored once `exports`
20
+ * exists). Throws if the package isn't installed/resolvable.
21
+ */
22
+ export declare function packageAssetDir(specifier: string): string;
12
23
  export interface AssetsRequest {
13
24
  /**
14
25
  * Read the wildcard `*` segment of the matched route. Most routers
@@ -10,7 +10,21 @@
10
10
  * `AssetsHttpContext` (Ream, AdonisJS, anything duck-typed) works.
11
11
  */
12
12
  import { readFile, realpath } from "node:fs/promises";
13
- import { extname, join, resolve as resolvePath, sep } from "node:path";
13
+ import { dirname, extname, join, resolve as resolvePath, sep } from "node:path";
14
+ import { fileURLToPath } from "node:url";
15
+ /**
16
+ * Absolute dist directory of an installed package — for mounting its pre-built
17
+ * ESM as browser assets (`serveAssets({ root: packageAssetDir('@c9up/x') })`).
18
+ *
19
+ * Uses `import.meta.resolve`, which honours the package's `exports` `import`
20
+ * condition — so it works for `@c9up/*` import-only packages where
21
+ * `createRequire().resolve()` throws `ERR_PACKAGE_PATH_NOT_EXPORTED` (their
22
+ * `exports` carry no `require` condition, and `main` is ignored once `exports`
23
+ * exists). Throws if the package isn't installed/resolvable.
24
+ */
25
+ export function packageAssetDir(specifier) {
26
+ return dirname(fileURLToPath(import.meta.resolve(specifier)));
27
+ }
14
28
  const CONTENT_TYPES = {
15
29
  ".js": "text/javascript; charset=utf-8",
16
30
  ".mjs": "text/javascript; charset=utf-8",
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export { AuroraManager, type AuroraManagerConfig } from "./AuroraManager.js";
2
2
  export { type PageFactory, Pages, type PagesConfig } from "./Pages.js";
3
3
  export { type RenderHttpContext, type RenderPageOptions, type RenderResponse, renderPage, } from "./server/renderPage.js";
4
- export { type AssetsHttpContext, type AssetsRequest, type AssetsResponse, type ServeAssetsOptions, serveAssets, } from "./server/serveAssets.js";
4
+ export { type AssetsHttpContext, type AssetsRequest, type AssetsResponse, packageAssetDir, type ServeAssetsOptions, serveAssets, } from "./server/serveAssets.js";
package/dist/server.js CHANGED
@@ -7,4 +7,4 @@
7
7
  export { AuroraManager } from "./AuroraManager.js";
8
8
  export { Pages } from "./Pages.js";
9
9
  export { renderPage, } from "./server/renderPage.js";
10
- export { serveAssets, } from "./server/serveAssets.js";
10
+ export { packageAssetDir, serveAssets, } from "./server/serveAssets.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c9up/aurora",
3
- "version": "0.1.17",
3
+ "version": "0.1.18",
4
4
  "description": "Aurora — reactive UI runtime for the Ream framework. Tagged-template DOM, signal-based state, isomorphic SSR + hydration, zero build step.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,7 +20,11 @@ import {
20
20
  type RenderPageOptions,
21
21
  renderPage,
22
22
  } from "./server/renderPage.js";
23
- import { type AssetsHttpContext, serveAssets } from "./server/serveAssets.js";
23
+ import {
24
+ type AssetsHttpContext,
25
+ packageAssetDir,
26
+ serveAssets,
27
+ } from "./server/serveAssets.js";
24
28
 
25
29
  export interface AuroraManagerConfig {
26
30
  pages: PagesConfig;
@@ -30,6 +34,13 @@ export interface AuroraManagerConfig {
30
34
  * Override only if you want to serve a custom build.
31
35
  */
32
36
  auroraDistRoot?: string;
37
+ /**
38
+ * Filesystem path to `@c9up/comet`'s `dist/`. Defaults to the dist of the
39
+ * installed (optional-peer) `@c9up/comet` — resolved automatically so the
40
+ * RPC client's `import '@c9up/comet'` works in the no-bundler browser with
41
+ * zero app wiring. Left unserved when comet isn't installed (no RPC).
42
+ */
43
+ cometDistRoot?: string;
33
44
  /**
34
45
  * URL prefix the asset routes mount under. The aurora runtime is served
35
46
  * from `<assetsPrefix>/aurora/*` and the app's pages from
@@ -46,6 +57,19 @@ const DEFAULT_AURORA_DIST = resolvePath(
46
57
  "../dist",
47
58
  );
48
59
 
60
+ /**
61
+ * Resolve `@c9up/comet`'s dist dir, or `null` when it isn't installed. comet is
62
+ * aurora's OPTIONAL peer (only present when the app uses RPC), so a missing one
63
+ * is expected — aurora then simply doesn't serve it or add it to the importmap.
64
+ */
65
+ function resolveCometDist(): string | null {
66
+ try {
67
+ return packageAssetDir("@c9up/comet");
68
+ } catch {
69
+ return null;
70
+ }
71
+ }
72
+
49
73
  /** Normalize an asset prefix: ensure a leading slash, drop trailing slashes. */
50
74
  function normalizePrefix(prefix: string): string {
51
75
  const withLead = prefix.startsWith("/") ? prefix : `/${prefix}`;
@@ -61,11 +85,17 @@ export class AuroraManager {
61
85
  readonly auroraAssetPath: string;
62
86
  /** Mount path for the app's pages — `<assetsPrefix>/pages`. */
63
87
  readonly pageAssetPath: string;
88
+ /** Mount path for the RPC client's `@c9up/comet` runtime — `<assetsPrefix>/comet`. */
89
+ readonly cometAssetPath: string;
90
+ /** Resolved `@c9up/comet` dist dir, or `null` when comet isn't installed. */
91
+ readonly cometDistRoot: string | null;
64
92
 
65
93
  constructor(config: AuroraManagerConfig) {
66
94
  this.assetsPrefix = normalizePrefix(config.assetsPrefix ?? "/_assets");
67
95
  this.auroraAssetPath = `${this.assetsPrefix}/aurora`;
68
96
  this.pageAssetPath = `${this.assetsPrefix}/pages`;
97
+ this.cometAssetPath = `${this.assetsPrefix}/comet`;
98
+ this.cometDistRoot = config.cometDistRoot ?? resolveCometDist();
69
99
  // Pages serve their compiled JS from the same prefix unless the app
70
100
  // pins an explicit urlPrefix.
71
101
  this.pages = new Pages({
@@ -91,6 +121,12 @@ export class AuroraManager {
91
121
  ...options,
92
122
  importmap: {
93
123
  "@c9up/aurora": `${this.auroraAssetPath}/index.js`,
124
+ // Auto-map @c9up/comet when installed so `@c9up/aurora/rpc`'s bare
125
+ // `import '@c9up/comet'` resolves in the no-bundler browser — no
126
+ // app-side importmap wiring. Omitted when comet isn't present.
127
+ ...(this.cometDistRoot
128
+ ? { "@c9up/comet": `${this.cometAssetPath}/index.js` }
129
+ : {}),
94
130
  ...options?.importmap,
95
131
  },
96
132
  });
@@ -111,4 +147,15 @@ export class AuroraManager {
111
147
  pageAssetsHandler(): (ctx: AssetsHttpContext) => Promise<void> {
112
148
  return serveAssets({ root: this.pages.root });
113
149
  }
150
+
151
+ /**
152
+ * Handler for `@c9up/comet`'s runtime (the RPC client). Mount on
153
+ * `GET <cometAssetPath>/*`. Returns `null` when comet isn't installed —
154
+ * the provider then skips the route (no RPC, nothing to serve).
155
+ */
156
+ cometAssetsHandler(): ((ctx: AssetsHttpContext) => Promise<void>) | null {
157
+ return this.cometDistRoot
158
+ ? serveAssets({ root: this.cometDistRoot })
159
+ : null;
160
+ }
114
161
  }
@@ -101,6 +101,13 @@ export default class AuroraProvider {
101
101
  `${manager.pageAssetPath}/*`,
102
102
  adaptHandler(manager.pageAssetsHandler()),
103
103
  );
104
+ // Serve @c9up/comet's runtime so the RPC client's bare `import
105
+ // '@c9up/comet'` resolves in the browser. Skipped when comet isn't
106
+ // installed (optional peer — the app doesn't use RPC).
107
+ const cometHandler = manager.cometAssetsHandler();
108
+ if (cometHandler) {
109
+ router.get(`${manager.cometAssetPath}/*`, adaptHandler(cometHandler));
110
+ }
104
111
  }
105
112
 
106
113
  async ready(): Promise<void> {}
@@ -11,7 +11,22 @@
11
11
  */
12
12
 
13
13
  import { readFile, realpath } from "node:fs/promises";
14
- import { extname, join, resolve as resolvePath, sep } from "node:path";
14
+ import { dirname, extname, join, resolve as resolvePath, sep } from "node:path";
15
+ import { fileURLToPath } from "node:url";
16
+
17
+ /**
18
+ * Absolute dist directory of an installed package — for mounting its pre-built
19
+ * ESM as browser assets (`serveAssets({ root: packageAssetDir('@c9up/x') })`).
20
+ *
21
+ * Uses `import.meta.resolve`, which honours the package's `exports` `import`
22
+ * condition — so it works for `@c9up/*` import-only packages where
23
+ * `createRequire().resolve()` throws `ERR_PACKAGE_PATH_NOT_EXPORTED` (their
24
+ * `exports` carry no `require` condition, and `main` is ignored once `exports`
25
+ * exists). Throws if the package isn't installed/resolvable.
26
+ */
27
+ export function packageAssetDir(specifier: string): string {
28
+ return dirname(fileURLToPath(import.meta.resolve(specifier)));
29
+ }
15
30
 
16
31
  const CONTENT_TYPES: Record<string, string> = {
17
32
  ".js": "text/javascript; charset=utf-8",
package/src/server.ts CHANGED
@@ -17,6 +17,7 @@ export {
17
17
  type AssetsHttpContext,
18
18
  type AssetsRequest,
19
19
  type AssetsResponse,
20
+ packageAssetDir,
20
21
  type ServeAssetsOptions,
21
22
  serveAssets,
22
23
  } from "./server/serveAssets.js";