@cavulsqa/create 2.4.0 → 2.5.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/README.md CHANGED
@@ -44,7 +44,7 @@ The `f7-app` template: a tabbed shell, a `domains` / `modules` / `shared` layout
44
44
  sales demo over a six-table schema — dashboard aggregates, search, an order sheet, swipe actions,
45
45
  a detail screen — with tests against real SQLite.
46
46
 
47
- Underneath it, the data layer this repository publishes: `@cavulsqa/mobile-db` for Capacitor SQLite
47
+ Underneath it, the data layer this repository publishes: `@cavulsqa/mobile-db` for OPFS SQLite
48
48
  under Kysely, `@cavulsqa/reactive-db` for the change bus, and `@cavulsqa/reactive-vue` for
49
49
  `useReactiveQuery`. A write announces the tables it touched and every query watching them refetches;
50
50
  nothing in a screen asks for a refresh.
@@ -0,0 +1,40 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+
4
+ /** Every publishable package under `packages/`, mapped to the version it currently declares. */
5
+ export function publishedVersions(repoRoot) {
6
+ const versions = new Map();
7
+ for (const dir of readdirSync(join(repoRoot, "packages")).sort()) {
8
+ const manifest = join(repoRoot, "packages", dir, "package.json");
9
+ if (!existsSync(manifest)) continue;
10
+ const pkg = JSON.parse(readFileSync(manifest, "utf8"));
11
+ if (!pkg.private) versions.set(pkg.name, pkg.version);
12
+ }
13
+ return versions;
14
+ }
15
+
16
+ /**
17
+ * The sibling packages the templates declare as `workspace:` deps, in the order they are named.
18
+ *
19
+ * These are the ones the bundler rewrites to a concrete `^` range, so they are the ones whose
20
+ * versions change what a published creator scaffolds.
21
+ */
22
+ export function workspaceDependencies(repoRoot) {
23
+ const names = new Set();
24
+ const templates = join(repoRoot, "templates");
25
+ if (!existsSync(templates)) return [];
26
+
27
+ for (const name of readdirSync(templates).sort()) {
28
+ const manifest = join(templates, name, "package.json");
29
+ if (!existsSync(manifest)) continue;
30
+ const pkg = JSON.parse(readFileSync(manifest, "utf8"));
31
+ for (const group of [pkg.dependencies, pkg.devDependencies]) {
32
+ for (const [dep, range] of Object.entries(group ?? {})) {
33
+ if (typeof range === "string" && range.startsWith("workspace:")) names.add(dep);
34
+ }
35
+ }
36
+ }
37
+ // Codepoint order, not locale order: this list is hashed, and the hash has to match on every
38
+ // machine that computes it.
39
+ return [...names].sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
40
+ }
@@ -1,19 +1,28 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import { createHash } from "node:crypto";
3
+ import { publishedVersions, workspaceDependencies } from "./publishedVersions.mjs";
3
4
 
4
5
  /**
5
- * A content hash of every tracked file under `templates/`, used to prove that `@cavulsqa/create`
6
- * was republished after the templates changed.
6
+ * A content hash of everything a published creator would bundle, used to prove that
7
+ * `@cavulsqa/create` was republished after any of it changed.
7
8
  *
8
9
  * The creator bundles the templates at pack time, so a template fix reaches nobody until a new
9
10
  * version of the creator goes out. Nothing about that is visible in a diff, which is exactly the
10
11
  * kind of coupling that gets forgotten - so it is checked rather than remembered.
11
12
  *
12
- * It asks git rather than walking the directory. Walking gave two different answers on a Windows
13
- * working copy and on a CI checkout, because the disk holds whatever each machine happens to have:
14
- * ignored files, build leftovers, and CRLF where the runner has LF. `git ls-files -s` reports the
15
- * blob hash recorded in the index, which is normalised, platform-independent, and - the point -
16
- * describes exactly what a `git clone` of this repository would produce.
13
+ * Two inputs, because the bundle has two:
14
+ *
15
+ * - The tracked files under `templates/`. It asks git rather than walking the directory. Walking
16
+ * gave two different answers on a Windows working copy and on a CI checkout, because the disk
17
+ * holds whatever each machine happens to have: ignored files, build leftovers, and CRLF where
18
+ * the runner has LF. `git ls-files -s` reports the blob hash recorded in the index, which is
19
+ * normalised, platform-independent, and - the point - describes exactly what a `git clone` of
20
+ * this repository would produce.
21
+ * - The sibling versions the bundler pins those templates to. A template declares
22
+ * `workspace:*` and the bundler rewrites it to `^<current version>`, so bumping a library
23
+ * changes what the creator scaffolds while leaving every tracked file byte-identical. Hashing
24
+ * the files alone said "unchanged" and let the creator keep shipping ranges that no longer
25
+ * admitted the packages it was meant to install.
17
26
  */
18
27
  export function fingerprintTemplates(repoRoot) {
19
28
  const listing = execFileSync("git", ["ls-files", "-s", "--", "templates"], {
@@ -25,5 +34,10 @@ export function fingerprintTemplates(repoRoot) {
25
34
  const lines = listing.split("\n").filter(Boolean).sort();
26
35
  if (!lines.length) throw new Error("git reports no tracked files under templates/");
27
36
 
28
- return `sha256-${createHash("sha256").update(lines.join("\n")).digest("base64")}`;
37
+ const versions = publishedVersions(repoRoot);
38
+ const pins = workspaceDependencies(repoRoot).map((name) => `${name}@${versions.get(name)}`);
39
+
40
+ return `sha256-${createHash("sha256")
41
+ .update([...lines, ...pins].join("\n"))
42
+ .digest("base64")}`;
29
43
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavulsqa/create",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Create a Vue + Framework7 + Capacitor + SQLite app from the cavulsqa templates.",
5
5
  "keywords": [
6
6
  "capacitor",
@@ -52,7 +52,7 @@
52
52
  }
53
53
  ]
54
54
  },
55
- "templatesFingerprint": "sha256-tG0kS6m1X1FkrDBDpzezvdSxTxaLazPunAi3a0xab7o=",
55
+ "templatesFingerprint": "sha256-cV0g/O7hz2eNNshfgmpNGWq7pcYKH/DRDVaeqkqVgjg=",
56
56
  "scripts": {
57
57
  "build": "node scripts/bundleTemplates.mjs",
58
58
  "check": "vp check",
@@ -10,15 +10,15 @@ SQLite — it does not become the thing screens read.
10
10
  ## Stack
11
11
 
12
12
  Vue 3.5 `<script setup lang="ts">` · Framework7 9 (+ framework7-vue 8) · Capacitor 8 (Android
13
- first) · Kysely over `@capacitor-community/sqlite` · vue-i18n · Tailwind 4 · Vite+ (`vp`).
13
+ first) · Kysely over SQLite in an OPFS worker · vue-i18n · Tailwind 4 · Vite+ (`vp`).
14
14
 
15
15
  Data layer comes from three published packages, not from this repo:
16
16
 
17
- | Package | What it gives you |
18
- | ------------------------ | ------------------------------------------------------------------ |
19
- | `@cavulsqa/mobile-db` | The Capacitor SQLite dialect, migrations, transaction-aware writes |
20
- | `@cavulsqa/reactive-db` | Change bus, result cache, visibility gate, query metrics |
21
- | `@cavulsqa/reactive-vue` | `useReactiveQuery` and the Framework7 page-visibility adapter |
17
+ | Package | What it gives you |
18
+ | ------------------------ | ------------------------------------------------------------- |
19
+ | `@cavulsqa/mobile-db` | The OPFS worker dialect, migrations, transaction-aware writes |
20
+ | `@cavulsqa/reactive-db` | Change bus, result cache, visibility gate, query metrics |
21
+ | `@cavulsqa/reactive-vue` | `useReactiveQuery` and the Framework7 page-visibility adapter |
22
22
 
23
23
  Do not vendor or fork them. If one is wrong, fix it there and bump the version.
24
24
 
@@ -19,9 +19,9 @@
19
19
  "@capacitor/preferences": "^8.0.0",
20
20
  "@capacitor/splash-screen": "^8.0.0",
21
21
  "@capacitor/status-bar": "^8.0.0",
22
- "@cavulsqa/mobile-db": "^0.6.0",
23
- "@cavulsqa/reactive-db": "^0.3.0",
24
- "@cavulsqa/reactive-vue": "^0.3.0",
22
+ "@cavulsqa/mobile-db": "^1.0.0",
23
+ "@cavulsqa/reactive-db": "^1.0.0",
24
+ "@cavulsqa/reactive-vue": "^1.0.0",
25
25
  "@sqlite.org/sqlite-wasm": "3.53.0-build1",
26
26
  "@tailwindcss/vite": "^4.3.3",
27
27
  "@vueuse/core": "^14.4.0",