rimecms 0.31.0 → 0.31.1

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.
@@ -2,6 +2,7 @@ import { RIME_DEV_CACHE_DIR } from '../../../constant.server.js';
2
2
  import cache from '../../cache/index.server.js';
3
3
  import { sanitize } from '../../generate/sanitize/index.server.js';
4
4
  import { ensureGeneratedConfig, ensureUserConfigExist } from '../../../ensure.server.js';
5
+ import { regenerateModulesDeclaration } from '../../vite/index.server.js';
5
6
  import { logger } from '../../../logger/index.server.js';
6
7
  import { trycatch } from '../../../../util/function.js';
7
8
  import { mkdirSync, rmSync } from 'fs';
@@ -67,6 +68,9 @@ export const generate = async (args) => {
67
68
  try {
68
69
  ensureUserConfigExist();
69
70
  await sanitizeConfig();
71
+ // Normal `vite dev` writes this from `configureServer`'s `listening` event, which never
72
+ // fires here — this command's own Vite server runs in `middlewareMode` (no `httpServer`).
73
+ regenerateModulesDeclaration();
70
74
  const importPathJS = ensureGeneratedConfig();
71
75
  logger.info('Starting vite server...');
72
76
  const vite = await createServer();
@@ -32,6 +32,10 @@ export declare function findModulePair(root: string, name: string): RuntimeRegis
32
32
  * `src/lib`-rooted scan registers as `fields/relation`. Used by the `$rime/modules` barrel
33
33
  * (live, dev-mode only) and by `generate-manifest` (once, at prepack, scanning `dist/`).
34
34
  *
35
+ * A pair sitting directly in `root` itself (e.g. `src/lib/module.ts`, no subfolder) registers
36
+ * under the key `.` — same convention `package.json`'s own `exports` map uses for a package's
37
+ * root, and a folder literally named `.` can't exist, so it can never collide with a real one.
38
+ *
35
39
  * Either file alone is enough to register (single-sided is legitimate — a server-only piece,
36
40
  * e.g. a collection's hooks, never needs a hand-written client stub; the missing side is just
37
41
  * an empty string here, same convention `findModulePair` above uses). `rime.generated/` is
@@ -57,6 +57,10 @@ export function findModulePair(root, name) {
57
57
  * `src/lib`-rooted scan registers as `fields/relation`. Used by the `$rime/modules` barrel
58
58
  * (live, dev-mode only) and by `generate-manifest` (once, at prepack, scanning `dist/`).
59
59
  *
60
+ * A pair sitting directly in `root` itself (e.g. `src/lib/module.ts`, no subfolder) registers
61
+ * under the key `.` — same convention `package.json`'s own `exports` map uses for a package's
62
+ * root, and a folder literally named `.` can't exist, so it can never collide with a real one.
63
+ *
60
64
  * Either file alone is enough to register (single-sided is legitimate — a server-only piece,
61
65
  * e.g. a collection's hooks, never needs a hand-written client stub; the missing side is just
62
66
  * an empty string here, same convention `findModulePair` above uses). `rime.generated/` is
@@ -66,17 +70,20 @@ export function scanModulePairs(root) {
66
70
  const registry = new Map();
67
71
  if (!fs.existsSync(root))
68
72
  return registry;
73
+ const register = (dir, key) => {
74
+ const client = findModuleFile(dir, 'module');
75
+ const server = findModuleFile(dir, 'module.server');
76
+ if (client || server) {
77
+ registry.set(key, { client: client ?? '', server: server ?? '' });
78
+ }
79
+ };
80
+ register(root, '.');
69
81
  const walk = (dir) => {
70
82
  for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
71
83
  if (!entry.isDirectory() || entry.name === OUTPUT_DIR)
72
84
  continue;
73
85
  const fullPath = path.join(dir, entry.name);
74
- const client = findModuleFile(fullPath, 'module');
75
- const server = findModuleFile(fullPath, 'module.server');
76
- if (client || server) {
77
- const key = path.relative(root, fullPath).split(path.sep).join('/');
78
- registry.set(key, { client: client ?? '', server: server ?? '' });
79
- }
86
+ register(fullPath, path.relative(root, fullPath).split(path.sep).join('/'));
80
87
  walk(fullPath);
81
88
  }
82
89
  };
@@ -1,2 +1,3 @@
1
1
  import type { Plugin } from 'vite';
2
+ export declare function regenerateModulesDeclaration(): void;
2
3
  export declare function rime(): Plugin;
@@ -38,6 +38,20 @@ function splitPackageSpecifier(rest) {
38
38
  const subpath = segments.slice(pkgName.split('/').length).join('/');
39
39
  return { pkgName, subpath };
40
40
  }
41
+ // Writes the local-dev $rime/modules barrel types from every module.(server.)ts pair under
42
+ // src/lib. Exported so the CLI `generate` command can call it too — its Vite server runs in
43
+ // middlewareMode, which never fires the `listening` event `rime()` normally hooks this to.
44
+ export function regenerateModulesDeclaration() {
45
+ const libDir = path.resolve(process.cwd(), 'src/lib');
46
+ const pairs = scanModulePairs(libDir);
47
+ const exports = Array.from(pairs.values())
48
+ .map((entry) => entry.server || entry.client)
49
+ .filter(Boolean)
50
+ .map((file) => `$lib/${path.relative(libDir, file).split(path.sep).join('/')}`.replace(/\.ts$/, '.js'))
51
+ .map((aliased) => ` export * from '${aliased}';`)
52
+ .join('\n');
53
+ writeFileSync(path.resolve(process.cwd(), 'src/rime.modules.generated.d.ts'), `declare module '$rime/modules' {\n${exports}\n}\n`);
54
+ }
41
55
  export function rime() {
42
56
  /** Two reserved names, always resolved to *the currently running app's* generated
43
57
  * config/schema, independent of who's asking — a third-party plugin importing
@@ -46,28 +60,19 @@ export function rime() {
46
60
  * namespace only by convention. */
47
61
  const VCoreId = '$rime/config';
48
62
  const VSchemaId = '$rime/schema';
49
- /** `$rime/modules` — a package's own client/server split, resolved relative to *whoever's
50
- * asking*, always self-contained. Two forms:
63
+ /**
64
+ * `$rime/modules` lets a package split its code into client and server files.
65
+ *
66
+ * While developing, you can just write `$rime/modules` with no path and it scans this
67
+ * project's own `src/lib` for every split. Before the package is published, that gets
68
+ * rewritten into explicit imports like `$rime/modules/<pkg>/<path>` — so anyone installing
69
+ * the package never sees the bare form, only real paths.
70
+ *
71
+ * When resolving one of those explicit imports: if `<pkg>` is this same project, we read
72
+ * straight from `src/lib`. Otherwise it's a real dependency, so we find it in
73
+ * `node_modules` and read the file list it shipped.
51
74
  *
52
- * - The bare barrel, `$rime/modules`, addressed by *export name* rather than path — dev
53
- * only, live-scans this project's own `src/lib` for every `module.(server.)ts` pair (see
54
- * `regenerateModulesDeclaration` below for the matching local-dev `.d.ts`). Never ships:
55
- * a prepack step (the `generate-manifest` CLI command) AST-rewrites every `$rime/modules`
56
- * import into the qualified form below before publish, so a consumer never sees the
57
- * barrel at all.
58
- * - The qualified form, `$rime/modules/<pkg>/<path>`, always package-qualified — even for a
59
- * package's own internal references to itself. Two ways it resolves, both in `resolveId`
60
- * (not `load`, which never receives `importer`): `<pkg>` equals this project's own
61
- * `package.json` name → self-reference, resolved directly off this project's own
62
- * `src/lib`. Otherwise → an installed dependency, its root found by walking up
63
- * `node_modules/<pkg>` from the importer's own directory (`findInstalledPackageRoot` —
64
- * pure directory existence, no `exports`-conditions matching, since a package whose
65
- * `exports` map declares only conditions neither `require.resolve` nor
66
- * `import.meta.resolve` use fails to resolve through either) and its shipped
67
- * `dist/.rime-modules.json` read directly — no directory-convention guessing beyond that,
68
- * immune to Vite's dep-optimizer flattening a package (reading a known filename off disk
69
- * never touches the import graph the optimizer rewrites). Full design:
70
- * docs/plans/imports.md. */
75
+ */
71
76
  const VModulesId = '$rime/modules';
72
77
  const VModulesPrefix = '$rime/modules/';
73
78
  const ownPackageName = getPackageInfoByKey('name');
@@ -77,25 +82,6 @@ export function rime() {
77
82
  // doesn't receive importer); the barrel and self-reference cases carry no baked-in root.
78
83
  const ROOT_SEP = '\x01';
79
84
  const resolvedVModule = (name) => '\0' + name;
80
- // Local-dev types for the $rime/modules barrel — declares every module.(server.)ts pair
81
- // currently under this project's own src/lib, live. Regenerated on startup and whenever a
82
- // module file appears/changes/disappears (see the watcher below) — never ships, gitignored,
83
- // same treatment as app.generated.d.ts/rime.generated.d.ts.
84
- //
85
- // $lib/-aliased paths, not bare relative/absolute ones — verified directly (a plain relative
86
- // or absolute `export * from` inside a `declare module` block silently resolves to no
87
- // exports at all; TS only picks up the re-exported names through a real configured alias).
88
- function regenerateModulesDeclaration() {
89
- const libDir = path.resolve(process.cwd(), 'src/lib');
90
- const pairs = scanModulePairs(libDir);
91
- const exports = Array.from(pairs.values())
92
- .map((entry) => entry.server || entry.client)
93
- .filter(Boolean)
94
- .map((file) => `$lib/${path.relative(libDir, file).split(path.sep).join('/')}`.replace(/\.ts$/, '.js'))
95
- .map((aliased) => ` export * from '${aliased}';`)
96
- .join('\n');
97
- writeFileSync(path.resolve(process.cwd(), 'src/rime.modules.generated.d.ts'), `declare module '$rime/modules' {\n${exports}\n}\n`);
98
- }
99
85
  return {
100
86
  name: 'virtual-rime',
101
87
  configureServer(server) {
@@ -196,9 +182,6 @@ export function rime() {
196
182
  },
197
183
  server: {
198
184
  watch: {
199
- // db/*.sqlite (+ its -wal/-shm sidecars) and logs/ are runtime data, not source —
200
- // every write (e.g. saving a document) touches them, and without this Vite's default
201
- // whole-project-root watch treats that churn as a source change and force-reloads.
202
185
  ignored: ['**/db/**', '**/logs/**']
203
186
  }
204
187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rimecms",
3
- "version": "0.31.0",
3
+ "version": "0.31.1",
4
4
  "homepage": "https://github.com/bienbiendev/rime",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
@@ -96,6 +96,8 @@
96
96
  "vite": "^8.0.8"
97
97
  },
98
98
  "devDependencies": {
99
+ "@changesets/changelog-github": "^1.0.0",
100
+ "@changesets/cli": "^3.0.1",
99
101
  "@eslint/compat": "^1.2.5",
100
102
  "@eslint/js": "^9.18.0",
101
103
  "@sveltejs/adapter-node": "^5.5.4",