kawaijs 0.1.11 → 0.1.13

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 (48) hide show
  1. package/README.md +51 -4
  2. package/dist/commands/build.d.ts +1 -0
  3. package/dist/commands/build.d.ts.map +1 -1
  4. package/dist/commands/build.js +152 -1147
  5. package/dist/commands/build.js.map +1 -1
  6. package/dist/commands/create.d.ts.map +1 -1
  7. package/dist/commands/create.js +132 -55
  8. package/dist/commands/create.js.map +1 -1
  9. package/dist/commands/dev.d.ts +1 -0
  10. package/dist/commands/dev.d.ts.map +1 -1
  11. package/dist/commands/dev.js +301 -1258
  12. package/dist/commands/dev.js.map +1 -1
  13. package/dist/commands/embed.d.ts +25 -0
  14. package/dist/commands/embed.d.ts.map +1 -0
  15. package/dist/commands/embed.js +110 -0
  16. package/dist/commands/embed.js.map +1 -0
  17. package/dist/commands/validate.d.ts.map +1 -1
  18. package/dist/commands/validate.js +104 -6
  19. package/dist/commands/validate.js.map +1 -1
  20. package/dist/config.d.ts +119 -0
  21. package/dist/config.d.ts.map +1 -0
  22. package/dist/config.js +93 -0
  23. package/dist/config.js.map +1 -0
  24. package/dist/i18n.d.ts +8 -0
  25. package/dist/i18n.d.ts.map +1 -0
  26. package/dist/i18n.js +49 -0
  27. package/dist/i18n.js.map +1 -0
  28. package/dist/index.d.ts +7 -1
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +68 -33
  31. package/dist/index.js.map +1 -1
  32. package/dist/parse-args.d.ts +29 -0
  33. package/dist/parse-args.d.ts.map +1 -0
  34. package/dist/parse-args.js +106 -0
  35. package/dist/parse-args.js.map +1 -0
  36. package/dist/pwa.d.ts +22 -0
  37. package/dist/pwa.d.ts.map +1 -0
  38. package/dist/pwa.js +151 -0
  39. package/dist/pwa.js.map +1 -0
  40. package/dist/runtime-bundle.d.ts +3 -0
  41. package/dist/runtime-bundle.d.ts.map +1 -0
  42. package/dist/runtime-bundle.js +76 -0
  43. package/dist/runtime-bundle.js.map +1 -0
  44. package/dist/seo.d.ts +81 -0
  45. package/dist/seo.d.ts.map +1 -0
  46. package/dist/seo.js +534 -0
  47. package/dist/seo.js.map +1 -0
  48. package/package.json +8 -7
package/dist/i18n.js ADDED
@@ -0,0 +1,49 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { loadProjectConfig } from './config.js';
4
+ /** Load `game/lang/<code>.json` string tables. */
5
+ export function loadLangTables(projectDir) {
6
+ const rootDir = path.resolve(process.cwd(), projectDir);
7
+ const candidates = [
8
+ path.join(rootDir, 'game', 'lang'),
9
+ path.join(rootDir, 'lang')
10
+ ];
11
+ const tables = {};
12
+ for (const dir of candidates) {
13
+ if (!fs.existsSync(dir) || !fs.statSync(dir).isDirectory())
14
+ continue;
15
+ for (const entry of fs.readdirSync(dir)) {
16
+ if (!entry.endsWith('.json'))
17
+ continue;
18
+ const code = entry.replace(/\.json$/i, '').toLowerCase();
19
+ try {
20
+ const raw = JSON.parse(fs.readFileSync(path.join(dir, entry), 'utf-8'));
21
+ const flat = {};
22
+ for (const [k, v] of Object.entries(raw)) {
23
+ if (typeof v === 'string')
24
+ flat[k] = v;
25
+ }
26
+ tables[code] = flat;
27
+ }
28
+ catch {
29
+ // skip invalid
30
+ }
31
+ }
32
+ }
33
+ return tables;
34
+ }
35
+ export function loadAchievementCatalog(projectDir) {
36
+ const config = loadProjectConfig(projectDir);
37
+ return [...(config.achievements ?? [])];
38
+ }
39
+ /** Attach i18n + achievement catalog onto a compiled story package. */
40
+ export function enrichStoryPackage(story, projectDir) {
41
+ const i18n = loadLangTables(projectDir);
42
+ const achievements = loadAchievementCatalog(projectDir);
43
+ return {
44
+ ...story,
45
+ i18n: Object.keys(i18n).length > 0 ? i18n : story.i18n,
46
+ achievements: achievements.length > 0 ? achievements : story.achievements
47
+ };
48
+ }
49
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIhD,kDAAkD;AAClD,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC;KAC3B,CAAC;IAEF,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;YAAE,SAAS;QACrE,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,SAAS;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACzD,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAGrE,CAAC;gBACF,MAAM,IAAI,GAA2B,EAAE,CAAC;gBACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBACzC,IAAI,OAAO,CAAC,KAAK,QAAQ;wBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBACzC,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,eAAe;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,kBAAkB,CAChC,KAAmB,EACnB,UAAkB;IAElB,MAAM,IAAI,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO;QACL,GAAG,KAAK;QACR,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI;QACtD,YAAY,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY;KAC1E,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -4,10 +4,16 @@ export * from '@kawaijs/runtime';
4
4
  export * from '@kawaijs/renderer-dom';
5
5
  export * from '@kawaijs/audio';
6
6
  export * from '@kawaijs/vite-plugin';
7
+ export * from './config.js';
8
+ export * from './parse-args.js';
9
+ export * from './pwa.js';
10
+ export * from './seo.js';
11
+ export * from './i18n.js';
7
12
  import { createProject } from './commands/create.js';
8
13
  import { validateProject } from './commands/validate.js';
9
14
  import { startDevServer } from './commands/dev.js';
10
15
  import { buildProject } from './commands/build.js';
11
- export { createProject, validateProject, startDevServer, buildProject };
16
+ import { buildEmbedSnippet } from './commands/embed.js';
17
+ export { createProject, validateProject, startDevServer, buildProject, buildEmbedSnippet };
12
18
  export declare function runCLI(args: string[]): void;
13
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAExE,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4E3C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAyB,MAAM,qBAAqB,CAAC;AAG/E,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC;AAE3F,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAuG3C"}
package/dist/index.js CHANGED
@@ -4,11 +4,19 @@ export * from '@kawaijs/runtime';
4
4
  export * from '@kawaijs/renderer-dom';
5
5
  export * from '@kawaijs/audio';
6
6
  export * from '@kawaijs/vite-plugin';
7
+ export * from './config.js';
8
+ export * from './parse-args.js';
9
+ export * from './pwa.js';
10
+ export * from './seo.js';
11
+ export * from './i18n.js';
12
+ import * as fs from 'node:fs';
7
13
  import { createProject } from './commands/create.js';
8
14
  import { validateProject } from './commands/validate.js';
9
15
  import { startDevServer } from './commands/dev.js';
10
16
  import { buildProject } from './commands/build.js';
11
- export { createProject, validateProject, startDevServer, buildProject };
17
+ import { buildEmbedSnippet, parseEmbedCommandArgs } from './commands/embed.js';
18
+ import { parseBuildCommandArgs, parseDevCommandArgs } from './parse-args.js';
19
+ export { createProject, validateProject, startDevServer, buildProject, buildEmbedSnippet };
12
20
  export function runCLI(args) {
13
21
  const command = args[0];
14
22
  switch (command) {
@@ -18,18 +26,35 @@ export function runCLI(args) {
18
26
  break;
19
27
  }
20
28
  case 'dev': {
21
- const targetPath = args[1] ?? '.';
22
- startDevServer(targetPath);
29
+ const parsed = parseDevCommandArgs(args);
30
+ startDevServer(parsed.projectDir, {
31
+ port: parsed.port,
32
+ startLabel: parsed.startLabel
33
+ });
23
34
  break;
24
35
  }
25
36
  case 'build': {
26
- const targetPath = args[1] ?? '.';
27
- const ok = buildProject(targetPath);
37
+ const parsed = parseBuildCommandArgs(args);
38
+ const ok = buildProject(parsed.projectDir, {
39
+ outDir: parsed.outDir,
40
+ startLabel: parsed.startLabel
41
+ });
28
42
  if (!ok) {
29
43
  process.exitCode = 1;
30
44
  }
31
45
  break;
32
46
  }
47
+ case 'embed': {
48
+ const parsed = parseEmbedCommandArgs(args);
49
+ const snippet = buildEmbedSnippet(parsed.projectDir, {
50
+ width: parsed.width,
51
+ height: parsed.height,
52
+ startLabel: parsed.startLabel,
53
+ src: parsed.src
54
+ });
55
+ console.log(snippet);
56
+ break;
57
+ }
33
58
  case 'validate': {
34
59
  const targetPath = args[1] ?? '.';
35
60
  const ok = validateProject(targetPath);
@@ -41,40 +66,50 @@ export function runCLI(args) {
41
66
  case 'version':
42
67
  case '-v':
43
68
  case '--version': {
44
- console.log('Kawaijs v0.1.2');
69
+ try {
70
+ const pkgUrl = new URL('../package.json', import.meta.url);
71
+ const pkg = JSON.parse(fs.readFileSync(pkgUrl, 'utf-8'));
72
+ console.log(`Kawaijs v${pkg.version}`);
73
+ }
74
+ catch {
75
+ console.log('Kawaijs v0.1.11');
76
+ }
45
77
  break;
46
78
  }
47
79
  case 'help':
48
80
  case '-h':
49
81
  case '--help':
50
82
  default: {
51
- console.log(`
52
- 🌸 Kawaijs — Web-Native Visual Novel Engine & Toolchain
53
-
54
- Usage:
55
- kawa <command> [arguments]
56
- kawaijs <command> [arguments]
57
-
58
- Commands:
59
- create <name> Scaffold a new visual novel project
60
- dev [path] Start the local development server (with live reload)
61
- build [path] Build a static production web bundle (dist/)
62
- validate [path] Validate Kawa Script syntax, labels, and links
63
- help Show this help message
64
- version Show version information
65
-
66
- Keyboard Shortcuts in Game:
67
- Space / Enter Advance dialogue
68
- Backspace Rollback (step back)
69
- S Open Save Game menu
70
- L Open Load Game menu
71
- H Open Dialogue History
72
- Escape Close active modal
73
-
74
- Example:
75
- kawa create my-novel
76
- cd my-novel
77
- kawa dev
83
+ console.log(`
84
+ 🌸 Kawaijs — Web-Native Visual Novel Engine & Toolchain
85
+
86
+ Usage:
87
+ kawa <command> [arguments]
88
+ kawaijs <command> [arguments]
89
+
90
+ Commands:
91
+ create <name> Scaffold a new visual novel project
92
+ dev [path] [--port N] [--at label]
93
+ Start the local development server (live reload)
94
+ build [path] [--out dir] [--at label]
95
+ Build a static production web bundle (dist/)
96
+ embed [path] [--width N] [--height N] [--at label] [--src url]
97
+ Print an iframe embed snippet (?embed=1)
98
+ validate [path] Validate Kawa Script syntax, labels, and links
99
+ help Show this help message
100
+ version Show version information
101
+
102
+ URL flags (browser):
103
+ ?at=<label> Deep-link into a label (skips main menu)
104
+ ?embed=1 Compact embed / iframe mode
105
+ ?continue=<token> Restore a shared continue-link save
106
+ ?lang=<code> Force string-table language (e.g. it)
107
+
108
+ Example:
109
+ kawa create my-novel
110
+ cd my-novel
111
+ kawa dev --at start
112
+ kawa embed --width 960 --height 540 --src https://you.example/game/
78
113
  `);
79
114
  break;
80
115
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;AAExE,MAAM,UAAU,MAAM,CAAC,IAAc;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAExB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC;YAC1C,aAAa,CAAC,WAAW,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QAED,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAClC,cAAc,CAAC,UAAU,CAAC,CAAC;YAC3B,MAAM;QACR,CAAC;QAED,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAClC,MAAM,EAAE,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;YAClC,MAAM,EAAE,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACR,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACvB,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,SAAS,CAAC;QACf,KAAK,IAAI,CAAC;QACV,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC9B,MAAM;QACR,CAAC;QAED,KAAK,MAAM,CAAC;QACZ,KAAK,IAAI,CAAC;QACV,KAAK,QAAQ,CAAC;QACd,OAAO,CAAC,CAAC,CAAC;YACR,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BjB,CAAC,CAAC;YACG,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface DevCommandArgs {
2
+ readonly projectDir: string;
3
+ readonly port?: number;
4
+ readonly startLabel?: string;
5
+ }
6
+ /**
7
+ * Parse `kawa dev [path] [--port N] [--at label]`.
8
+ */
9
+ export declare function parseDevCommandArgs(args: string[]): DevCommandArgs;
10
+ export interface BuildCommandArgs {
11
+ readonly projectDir: string;
12
+ readonly startLabel?: string;
13
+ readonly outDir?: string;
14
+ }
15
+ /**
16
+ * Parse `kawa build [path] [--at label] [--out dir]`.
17
+ */
18
+ export declare function parseBuildCommandArgs(args: string[]): BuildCommandArgs;
19
+ export interface StaticMetaInput {
20
+ readonly title: string;
21
+ readonly description?: string;
22
+ readonly image?: string;
23
+ readonly siteName?: string;
24
+ readonly url?: string;
25
+ }
26
+ export declare function escapeHtmlAttr(value: string): string;
27
+ /** Static Open Graph / Twitter tags for dev/build HTML shells. */
28
+ export declare function renderStaticShareMetaTags(input: StaticMetaInput): string;
29
+ //# sourceMappingURL=parse-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-args.d.ts","sourceRoot":"","sources":["../src/parse-args.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,cAAc,CAkClE;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAgCtE;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMpD;AAED,kEAAkE;AAClE,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CA2BxE"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Parse `kawa dev [path] [--port N] [--at label]`.
3
+ */
4
+ export function parseDevCommandArgs(args) {
5
+ let projectDir = '.';
6
+ let port;
7
+ let startLabel;
8
+ for (let i = 1; i < args.length; i++) {
9
+ const token = args[i];
10
+ if (!token)
11
+ continue;
12
+ if (token.startsWith('--at=')) {
13
+ startLabel = token.slice(5).trim() || undefined;
14
+ continue;
15
+ }
16
+ if (token === '--at') {
17
+ startLabel = args[++i]?.trim() || undefined;
18
+ continue;
19
+ }
20
+ if (token.startsWith('--port=')) {
21
+ const n = Number(token.slice(7));
22
+ if (Number.isFinite(n) && n > 0)
23
+ port = n;
24
+ continue;
25
+ }
26
+ if (token === '--port') {
27
+ const n = Number(args[++i]);
28
+ if (Number.isFinite(n) && n > 0)
29
+ port = n;
30
+ continue;
31
+ }
32
+ if (token.startsWith('-')) {
33
+ continue;
34
+ }
35
+ projectDir = token;
36
+ }
37
+ return { projectDir, port, startLabel };
38
+ }
39
+ /**
40
+ * Parse `kawa build [path] [--at label] [--out dir]`.
41
+ */
42
+ export function parseBuildCommandArgs(args) {
43
+ let projectDir = '.';
44
+ let startLabel;
45
+ let outDir;
46
+ for (let i = 1; i < args.length; i++) {
47
+ const token = args[i];
48
+ if (!token)
49
+ continue;
50
+ if (token.startsWith('--at=')) {
51
+ startLabel = token.slice(5).trim() || undefined;
52
+ continue;
53
+ }
54
+ if (token === '--at') {
55
+ startLabel = args[++i]?.trim() || undefined;
56
+ continue;
57
+ }
58
+ if (token.startsWith('--out=')) {
59
+ outDir = token.slice(6).trim() || undefined;
60
+ continue;
61
+ }
62
+ if (token === '--out') {
63
+ outDir = args[++i]?.trim() || undefined;
64
+ continue;
65
+ }
66
+ if (token.startsWith('-')) {
67
+ continue;
68
+ }
69
+ projectDir = token;
70
+ }
71
+ return { projectDir, startLabel, outDir };
72
+ }
73
+ export function escapeHtmlAttr(value) {
74
+ return value
75
+ .replace(/&/g, '&amp;')
76
+ .replace(/</g, '&lt;')
77
+ .replace(/>/g, '&gt;')
78
+ .replace(/"/g, '&quot;');
79
+ }
80
+ /** Static Open Graph / Twitter tags for dev/build HTML shells. */
81
+ export function renderStaticShareMetaTags(input) {
82
+ const title = escapeHtmlAttr(input.title);
83
+ const description = escapeHtmlAttr(input.description ?? input.title);
84
+ const siteName = input.siteName ? escapeHtmlAttr(input.siteName) : title;
85
+ const image = input.image ? escapeHtmlAttr(input.image) : '';
86
+ const url = input.url ? escapeHtmlAttr(input.url) : '';
87
+ const lines = [
88
+ `<meta name="description" content="${description}">`,
89
+ `<meta property="og:type" content="website">`,
90
+ `<meta property="og:title" content="${title}">`,
91
+ `<meta property="og:description" content="${description}">`,
92
+ `<meta property="og:site_name" content="${siteName}">`,
93
+ `<meta name="twitter:card" content="summary_large_image">`,
94
+ `<meta name="twitter:title" content="${title}">`,
95
+ `<meta name="twitter:description" content="${description}">`
96
+ ];
97
+ if (image) {
98
+ lines.push(`<meta property="og:image" content="${image}">`);
99
+ lines.push(`<meta name="twitter:image" content="${image}">`);
100
+ }
101
+ if (url) {
102
+ lines.push(`<meta property="og:url" content="${url}">`);
103
+ }
104
+ return lines.map((l) => ` ${l}`).join('\n');
105
+ }
106
+ //# sourceMappingURL=parse-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-args.js","sourceRoot":"","sources":["../src/parse-args.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAc;IAChD,IAAI,UAAU,GAAG,GAAG,CAAC;IACrB,IAAI,IAAwB,CAAC;IAC7B,IAAI,UAA8B,CAAC;IAEnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;YAChD,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAChC,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,IAAI,GAAG,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,IAAI,GAAG,CAAC,CAAC;YAC1C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,UAAU,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAC1C,CAAC;AAQD;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,IAAI,UAAU,GAAG,GAAG,CAAC;IACrB,IAAI,UAA8B,CAAC;IACnC,IAAI,MAA0B,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;YAChD,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YACrB,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/B,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,SAAS,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;YACxC,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,SAAS;QACX,CAAC;QACD,UAAU,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAC5C,CAAC;AAUD,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAC7B,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,yBAAyB,CAAC,KAAsB;IAC9D,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,cAAc,CAAC,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;IACrE,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACzE,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,MAAM,KAAK,GAAG;QACZ,qCAAqC,WAAW,IAAI;QACpD,6CAA6C;QAC7C,sCAAsC,KAAK,IAAI;QAC/C,4CAA4C,WAAW,IAAI;QAC3D,0CAA0C,QAAQ,IAAI;QACtD,0DAA0D;QAC1D,uCAAuC,KAAK,IAAI;QAChD,6CAA6C,WAAW,IAAI;KAC7D,CAAC;IAEF,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,CAAC,IAAI,CAAC,sCAAsC,KAAK,IAAI,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,uCAAuC,KAAK,IAAI,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,GAAG,EAAE,CAAC;QACR,KAAK,CAAC,IAAI,CAAC,oCAAoC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC"}
package/dist/pwa.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { KawaProjectConfig } from './config.js';
2
+ export interface PwaAssets {
3
+ readonly manifestJson: string;
4
+ readonly serviceWorkerJs: string;
5
+ readonly iconSvg: string;
6
+ }
7
+ export interface WebManifestOptions {
8
+ /** Icon file in dist, e.g. `icon.svg` or `icon.png`. */
9
+ readonly iconFile?: string;
10
+ readonly iconMime?: string;
11
+ }
12
+ export declare function buildPwaIconSvg(accent?: string): string;
13
+ export declare function buildWebManifest(config: KawaProjectConfig, options?: WebManifestOptions): string;
14
+ /** App-shell service worker: precache core files, cache-first for assets. */
15
+ export declare function buildServiceWorkerScript(cacheVersion?: string, precacheExtra?: string[]): string;
16
+ export declare function buildPwaAssets(config: KawaProjectConfig, cacheVersion?: string, options?: WebManifestOptions & {
17
+ precacheExtra?: string[];
18
+ }): PwaAssets;
19
+ /** HTML tags for PWA installability (favicon/SEO icons come from seo.ts). */
20
+ export declare function renderPwaHeadTags(config: KawaProjectConfig): string;
21
+ export declare function renderPwaRegisterScript(): string;
22
+ //# sourceMappingURL=pwa.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pwa.d.ts","sourceRoot":"","sources":["../src/pwa.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,wDAAwD;IACxD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,eAAe,CAAC,MAAM,SAAY,GAAG,MAAM,CAW1D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,kBAAuB,GAC/B,MAAM,CA6CR;AAED,6EAA6E;AAC7E,wBAAgB,wBAAwB,CACtC,YAAY,SAAY,EACxB,aAAa,GAAE,MAAM,EAAO,GAC3B,MAAM,CA8DR;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,iBAAiB,EACzB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,GAAE,kBAAkB,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;CAAO,GAC9D,SAAS,CAWX;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAgBnE;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAQhD"}
package/dist/pwa.js ADDED
@@ -0,0 +1,151 @@
1
+ export function buildPwaIconSvg(accent = '#f43f5e') {
2
+ const safe = accent.replace(/[<>"']/g, '');
3
+ return `<?xml version="1.0" encoding="UTF-8"?>
4
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Kawaijs">
5
+ <rect width="512" height="512" rx="96" fill="#0f172a"/>
6
+ <circle cx="256" cy="210" r="110" fill="${safe}" opacity="0.95"/>
7
+ <path d="M120 400c40-70 100-100 136-100s96 30 136 100" fill="none" stroke="${safe}" stroke-width="28" stroke-linecap="round"/>
8
+ <circle cx="210" cy="190" r="14" fill="#0f172a"/>
9
+ <circle cx="302" cy="190" r="14" fill="#0f172a"/>
10
+ </svg>
11
+ `;
12
+ }
13
+ export function buildWebManifest(config, options = {}) {
14
+ const name = config.title || 'Kawaijs Visual Novel';
15
+ const shortName = (config.pwa?.shortName || name).slice(0, 12);
16
+ const themeColor = config.seo?.themeColor || config.pwa?.themeColor || config.theme?.primaryColor || '#f43f5e';
17
+ const backgroundColor = config.pwa?.backgroundColor || '#000000';
18
+ const description = config.seo?.description ||
19
+ config.share?.description ||
20
+ config.pwa?.description ||
21
+ `Play ${name} in your browser.`;
22
+ const iconFile = options.iconFile || 'icon.svg';
23
+ const iconMime = options.iconMime ||
24
+ (iconFile.endsWith('.png') ? 'image/png' : 'image/svg+xml');
25
+ const lang = (config.seo?.locale || 'en_US').split(/[_-]/)[0] || 'en';
26
+ const manifest = {
27
+ name,
28
+ short_name: shortName,
29
+ description,
30
+ start_url: './index.html',
31
+ scope: './',
32
+ display: 'standalone',
33
+ orientation: 'any',
34
+ background_color: backgroundColor,
35
+ theme_color: themeColor,
36
+ lang,
37
+ icons: [
38
+ {
39
+ src: `./${iconFile}`,
40
+ sizes: 'any',
41
+ type: iconMime,
42
+ purpose: 'any'
43
+ },
44
+ {
45
+ src: `./${iconFile}`,
46
+ sizes: 'any',
47
+ type: iconMime,
48
+ purpose: 'maskable'
49
+ }
50
+ ]
51
+ };
52
+ return `${JSON.stringify(manifest, null, 2)}\n`;
53
+ }
54
+ /** App-shell service worker: precache core files, cache-first for assets. */
55
+ export function buildServiceWorkerScript(cacheVersion = 'kawa-v1', precacheExtra = []) {
56
+ const precache = [
57
+ './',
58
+ './index.html',
59
+ './style.css',
60
+ './manifest.webmanifest',
61
+ './icon.svg',
62
+ ...precacheExtra
63
+ ];
64
+ const unique = [...new Set(precache)];
65
+ return `/* Kawaijs PWA service worker */
66
+ const CACHE = '${cacheVersion}';
67
+ const PRECACHE = ${JSON.stringify(unique)};
68
+
69
+ self.addEventListener('install', (event) => {
70
+ event.waitUntil(
71
+ caches.open(CACHE).then((cache) => cache.addAll(PRECACHE)).then(() => self.skipWaiting())
72
+ );
73
+ });
74
+
75
+ self.addEventListener('activate', (event) => {
76
+ event.waitUntil(
77
+ caches.keys().then((keys) =>
78
+ Promise.all(keys.filter((k) => k !== CACHE).map((k) => caches.delete(k)))
79
+ ).then(() => self.clients.claim())
80
+ );
81
+ });
82
+
83
+ self.addEventListener('fetch', (event) => {
84
+ const req = event.request;
85
+ if (req.method !== 'GET') return;
86
+ const url = new URL(req.url);
87
+ if (url.origin !== self.location.origin) return;
88
+
89
+ const isAsset =
90
+ url.pathname.includes('/assets/') ||
91
+ /\\.(png|jpe?g|webp|gif|svg|ico|mp3|ogg|wav|m4a|css|js|woff2?)$/i.test(url.pathname);
92
+
93
+ if (isAsset) {
94
+ event.respondWith(
95
+ caches.open(CACHE).then(async (cache) => {
96
+ const hit = await cache.match(req);
97
+ if (hit) return hit;
98
+ const res = await fetch(req);
99
+ if (res.ok) cache.put(req, res.clone());
100
+ return res;
101
+ })
102
+ );
103
+ return;
104
+ }
105
+
106
+ event.respondWith(
107
+ fetch(req)
108
+ .then(async (res) => {
109
+ const cache = await caches.open(CACHE);
110
+ if (res.ok) cache.put(req, res.clone());
111
+ return res;
112
+ })
113
+ .catch(() => caches.match(req).then((hit) => hit || caches.match('./index.html')))
114
+ );
115
+ });
116
+ `;
117
+ }
118
+ export function buildPwaAssets(config, cacheVersion, options = {}) {
119
+ const accent = config.seo?.themeColor || config.pwa?.themeColor || config.theme?.primaryColor || '#f43f5e';
120
+ return {
121
+ manifestJson: buildWebManifest(config, options),
122
+ serviceWorkerJs: buildServiceWorkerScript(cacheVersion ?? `kawa-${Date.now().toString(36)}`, options.precacheExtra),
123
+ iconSvg: buildPwaIconSvg(accent)
124
+ };
125
+ }
126
+ /** HTML tags for PWA installability (favicon/SEO icons come from seo.ts). */
127
+ export function renderPwaHeadTags(config) {
128
+ const themeColor = (config.seo?.themeColor ||
129
+ config.pwa?.themeColor ||
130
+ config.theme?.primaryColor ||
131
+ '#f43f5e').replace(/[<>"']/g, '');
132
+ const title = (config.title || 'Kawaijs Visual Novel').replace(/[<>"']/g, '');
133
+ return [
134
+ ` <meta name="mobile-web-app-capable" content="yes">`,
135
+ ` <meta name="apple-mobile-web-app-capable" content="yes">`,
136
+ ` <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">`,
137
+ ` <meta name="apple-mobile-web-app-title" content="${title.slice(0, 12)}">`,
138
+ ` <meta name="theme-color" content="${themeColor}">`,
139
+ ` <link rel="manifest" href="./manifest.webmanifest">`
140
+ ].join('\n');
141
+ }
142
+ export function renderPwaRegisterScript() {
143
+ return `
144
+ if ('serviceWorker' in navigator) {
145
+ window.addEventListener('load', () => {
146
+ navigator.serviceWorker.register('./sw.js').catch(() => {});
147
+ });
148
+ }
149
+ `;
150
+ }
151
+ //# sourceMappingURL=pwa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pwa.js","sourceRoot":"","sources":["../src/pwa.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getBaseThemeCss(): string;
2
+ export declare function getInlineRuntimeScript(assetPrefix?: string): string;
3
+ //# sourceMappingURL=runtime-bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-bundle.d.ts","sourceRoot":"","sources":["../src/runtime-bundle.ts"],"names":[],"mappings":"AAQA,wBAAgB,eAAe,IAAI,MAAM,CA0BxC;AAwBD,wBAAgB,sBAAsB,CAAC,WAAW,SAAM,GAAG,MAAM,CAyBhE"}