@nilvn/core 0.14.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/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/catalog.d.ts +54 -0
- package/dist/catalog.js +137 -0
- package/dist/chunk-build.d.ts +37 -0
- package/dist/chunk-build.js +187 -0
- package/dist/chunk.d.ts +106 -0
- package/dist/chunk.js +35 -0
- package/dist/commands.d.ts +4 -0
- package/dist/commands.js +181 -0
- package/dist/i18n.d.ts +50 -0
- package/dist/i18n.js +77 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +17 -0
- package/dist/ir.d.ts +407 -0
- package/dist/ir.js +167 -0
- package/dist/package.d.ts +100 -0
- package/dist/package.js +80 -0
- package/dist/plugin-manifest.d.ts +146 -0
- package/dist/plugin-manifest.js +165 -0
- package/dist/plugins.d.ts +26 -0
- package/dist/plugins.js +42 -0
- package/dist/schema.d.ts +73 -0
- package/dist/schema.js +15 -0
- package/dist/screenplay-format.d.ts +8 -0
- package/dist/screenplay-format.js +96 -0
- package/dist/screenplay.d.ts +99 -0
- package/dist/screenplay.js +161 -0
- package/dist/semver.d.ts +15 -0
- package/dist/semver.js +129 -0
- package/dist/serialize.d.ts +63 -0
- package/dist/serialize.js +365 -0
- package/dist/versions.d.ts +17 -0
- package/dist/versions.js +25 -0
- package/package.json +42 -0
package/dist/commands.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
// Schemas for the engine's built-in CommandNode commands, grounded in
|
|
2
|
+
// packages/engine/src/builtins.ts. These drive the editor's command palette and forms.
|
|
3
|
+
//
|
|
4
|
+
// Excluded on purpose:
|
|
5
|
+
// - use / alias / actor -> project setup (Project.plugins / alias / actors), not nodes
|
|
6
|
+
// - jump / if / set -> first-class node kinds (JumpNode / JumpNode+condition / SetNode)
|
|
7
|
+
export const BUILTIN_COMMANDS = [
|
|
8
|
+
{
|
|
9
|
+
name: 'bg',
|
|
10
|
+
label: 'cmd.bg.label',
|
|
11
|
+
category: 'stage',
|
|
12
|
+
icon: '๐ผ',
|
|
13
|
+
hint: 'cmd.bg.hint',
|
|
14
|
+
params: [
|
|
15
|
+
{ key: 'bg', label: 'cmd.bg.bg', type: 'asset:bg', positional: 0 },
|
|
16
|
+
{ key: 'color', label: 'cmd.bg.color', type: 'color' },
|
|
17
|
+
{ key: 'fade', label: 'cmd.bg.fade', type: 'number', default: 0 },
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: 'char',
|
|
22
|
+
label: 'cmd.char.label',
|
|
23
|
+
category: 'stage',
|
|
24
|
+
icon: '๐ง',
|
|
25
|
+
hint: 'cmd.char.hint',
|
|
26
|
+
params: [
|
|
27
|
+
{ key: 'id', label: 'cmd.char.id', type: 'actor', required: true, positional: 0 },
|
|
28
|
+
{ key: 'face', label: 'cmd.char.face', type: 'face', positional: 1 },
|
|
29
|
+
{
|
|
30
|
+
key: 'at',
|
|
31
|
+
label: 'cmd.char.at',
|
|
32
|
+
type: 'enum',
|
|
33
|
+
options: [
|
|
34
|
+
{ value: 'left', label: 'cmd.char.at.left' },
|
|
35
|
+
{ value: 'center', label: 'cmd.char.at.center' },
|
|
36
|
+
{ value: 'right', label: 'cmd.char.at.right' },
|
|
37
|
+
],
|
|
38
|
+
},
|
|
39
|
+
// Birth transform โ written by the stage drag / scale / rotate handles (4c-4).
|
|
40
|
+
// NO schema default: these channels carry forward (an absent param means "keep
|
|
41
|
+
// the previous value", not "identity"), so the serializer must never drop an
|
|
42
|
+
// explicit identity that overrides an inherited non-identity value.
|
|
43
|
+
{ key: 'y', label: 'cmd.char.y', type: 'number', advanced: true },
|
|
44
|
+
{ key: 'scale', label: 'cmd.char.scale', type: 'number', advanced: true },
|
|
45
|
+
{ key: 'rotation', label: 'cmd.char.rotation', type: 'number', advanced: true },
|
|
46
|
+
{ key: 'fade', label: 'cmd.char.fade', type: 'number', default: 0.3 },
|
|
47
|
+
{ key: 'src', label: 'cmd.char.src', type: 'string', advanced: true },
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'hide',
|
|
52
|
+
label: 'cmd.hide.label',
|
|
53
|
+
category: 'stage',
|
|
54
|
+
icon: '๐ช',
|
|
55
|
+
params: [
|
|
56
|
+
{ key: 'id', label: 'cmd.hide.id', type: 'actor', required: true, positional: 0 },
|
|
57
|
+
{ key: 'fade', label: 'cmd.hide.fade', type: 'number', default: 0.3 },
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'clear',
|
|
62
|
+
label: 'cmd.clear.label',
|
|
63
|
+
category: 'stage',
|
|
64
|
+
icon: '๐งน',
|
|
65
|
+
hint: 'cmd.clear.hint',
|
|
66
|
+
params: [{ key: 'fade', label: 'cmd.clear.fade', type: 'number', default: 0.3 }],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'wait',
|
|
70
|
+
label: 'cmd.wait.label',
|
|
71
|
+
category: 'flow',
|
|
72
|
+
icon: 'โฑ',
|
|
73
|
+
hint: 'cmd.wait.hint',
|
|
74
|
+
params: [{ key: 'sec', label: 'cmd.wait.sec', type: 'number', required: true, default: 0.5, positional: 0 }],
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'fadeout',
|
|
78
|
+
label: 'cmd.fadeout.label',
|
|
79
|
+
category: 'fx',
|
|
80
|
+
icon: '๐',
|
|
81
|
+
params: [
|
|
82
|
+
{ key: 'sec', label: 'cmd.fadeout.sec', type: 'number', default: 0.6, positional: 0 },
|
|
83
|
+
{ key: 'color', label: 'cmd.fadeout.color', type: 'color', default: '#000' },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'fadein',
|
|
88
|
+
label: 'cmd.fadein.label',
|
|
89
|
+
category: 'fx',
|
|
90
|
+
icon: '๐',
|
|
91
|
+
params: [{ key: 'sec', label: 'cmd.fadein.sec', type: 'number', default: 0.6, positional: 0 }],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'dialog',
|
|
95
|
+
label: 'cmd.dialog.label',
|
|
96
|
+
category: 'stage',
|
|
97
|
+
icon: '๐ฌ',
|
|
98
|
+
hint: 'cmd.dialog.hint',
|
|
99
|
+
params: [
|
|
100
|
+
{
|
|
101
|
+
key: 'mode',
|
|
102
|
+
label: 'cmd.dialog.mode',
|
|
103
|
+
type: 'enum',
|
|
104
|
+
default: 'show',
|
|
105
|
+
positional: 0,
|
|
106
|
+
options: [
|
|
107
|
+
{ value: 'show', label: 'cmd.dialog.mode.show' },
|
|
108
|
+
{ value: 'hide', label: 'cmd.dialog.mode.hide' },
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'window',
|
|
115
|
+
label: 'cmd.window.label',
|
|
116
|
+
category: 'stage',
|
|
117
|
+
icon: '๐ช',
|
|
118
|
+
hint: 'cmd.window.hint',
|
|
119
|
+
params: [
|
|
120
|
+
// The skin picker reuses the background asset pool (a window texture is a
|
|
121
|
+
// flat image like a bg); type `skin=none` by hand to restore the default.
|
|
122
|
+
{ key: 'skin', label: 'cmd.window.skin', type: 'asset:bg', required: true, positional: 0 },
|
|
123
|
+
{ key: 'target', label: 'cmd.window.target', type: 'string', default: 'dialog', advanced: true },
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: 'textspeed',
|
|
128
|
+
label: 'cmd.textspeed.label',
|
|
129
|
+
category: 'text',
|
|
130
|
+
icon: 'โฉ',
|
|
131
|
+
hint: 'cmd.textspeed.hint',
|
|
132
|
+
params: [{ key: 'cps', label: 'cmd.textspeed.cps', type: 'number', default: 40, positional: 0 }],
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'bgm',
|
|
136
|
+
label: 'cmd.bgm.label',
|
|
137
|
+
category: 'audio',
|
|
138
|
+
icon: '๐ต',
|
|
139
|
+
params: [
|
|
140
|
+
{ key: 'bgm', label: 'cmd.bgm.bgm', type: 'asset:bgm', required: true, positional: 0 },
|
|
141
|
+
{ key: 'loop', label: 'cmd.bgm.loop', type: 'boolean', default: true },
|
|
142
|
+
{ key: 'volume', label: 'cmd.bgm.volume', type: 'number', default: 1 },
|
|
143
|
+
// Multi-track: 'music' = the classic BGM slot; any other name is an
|
|
144
|
+
// ambience bed layered alongside (its own loop channel + master volume).
|
|
145
|
+
{ key: 'track', label: 'cmd.bgm.track', type: 'string', default: 'music', advanced: true },
|
|
146
|
+
{ key: 'fade', label: 'cmd.bgm.fade', type: 'number', default: 0, advanced: true },
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'stopbgm',
|
|
151
|
+
label: 'cmd.stopbgm.label',
|
|
152
|
+
category: 'audio',
|
|
153
|
+
icon: '๐',
|
|
154
|
+
params: [
|
|
155
|
+
{ key: 'fade', label: 'cmd.stopbgm.fade', type: 'number', default: 0 },
|
|
156
|
+
{ key: 'track', label: 'cmd.stopbgm.track', type: 'string', default: 'music', advanced: true },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'se',
|
|
161
|
+
label: 'cmd.se.label',
|
|
162
|
+
category: 'audio',
|
|
163
|
+
icon: '๐',
|
|
164
|
+
params: [
|
|
165
|
+
{ key: 'se', label: 'cmd.se.se', type: 'asset:se', required: true, positional: 0 },
|
|
166
|
+
{ key: 'volume', label: 'cmd.se.volume', type: 'number', default: 1 },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
name: 'end',
|
|
171
|
+
label: 'cmd.end.label',
|
|
172
|
+
category: 'flow',
|
|
173
|
+
icon: '๐',
|
|
174
|
+
hint: 'cmd.end.hint',
|
|
175
|
+
params: [{ key: 'sec', label: 'cmd.end.sec', type: 'number', default: 1, positional: 0 }],
|
|
176
|
+
},
|
|
177
|
+
];
|
|
178
|
+
export const BUILTIN_COMMAND_MAP = Object.fromEntries(BUILTIN_COMMANDS.map((c) => [c.name, c]));
|
|
179
|
+
export function getCommandSchema(name) {
|
|
180
|
+
return BUILTIN_COMMAND_MAP[name];
|
|
181
|
+
}
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export type Catalog = Record<string, string>;
|
|
2
|
+
export type Params = Record<string, string | number>;
|
|
3
|
+
/** Namespaced, per-language catalogs as produced by a LocaleLoader.
|
|
4
|
+
* Shape: `{ [namespace]: { [lang]: { [id]: text } } }`. Namespaces (`editor`,
|
|
5
|
+
* `core`, `engine`, `plugin:<id>`) are an authoring/override grouping โ the
|
|
6
|
+
* runtime merges them flat because ids are already globally unique. */
|
|
7
|
+
export interface LoadedCatalogs {
|
|
8
|
+
[namespace: string]: {
|
|
9
|
+
[lang: string]: Catalog;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
/** Loads the catalogs for a host (web glob, Tauri resources + user overrides, or
|
|
13
|
+
* an inline injected blob for the engine's offline single-file export). */
|
|
14
|
+
export interface LocaleLoader {
|
|
15
|
+
load(): Promise<LoadedCatalogs>;
|
|
16
|
+
}
|
|
17
|
+
export interface I18n {
|
|
18
|
+
/** Switch the active language (unknown languages just miss into the base). */
|
|
19
|
+
setLocale(lang: string): void;
|
|
20
|
+
getLocale(): string;
|
|
21
|
+
/** Merge one language's catalog. `namespace` is advisory (kept for override
|
|
22
|
+
* composition at the loader layer); lookup is flat since ids are unique.
|
|
23
|
+
* Idempotent, last-write-wins per id. */
|
|
24
|
+
registerCatalog(namespace: string, lang: string, catalog: Catalog): void;
|
|
25
|
+
/** Resolve `id` for the active language: active โ base โ id. `{name}`
|
|
26
|
+
* placeholders are filled from `params` (in every language). */
|
|
27
|
+
t(id: string, params?: Params): string;
|
|
28
|
+
/** Whether `id` resolves to a real string (in the active or base language). */
|
|
29
|
+
has(id: string): boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Create an i18n instance. `base` (default `en`) is the guaranteed-complete
|
|
32
|
+
* fallback language; `active` defaults to `base`. */
|
|
33
|
+
export declare function createI18n(opts?: {
|
|
34
|
+
base?: string;
|
|
35
|
+
active?: string;
|
|
36
|
+
}): I18n;
|
|
37
|
+
/** Register every namespace/language of a LoadedCatalogs into an instance. */
|
|
38
|
+
export declare function applyCatalogs(i18n: I18n, loaded: LoadedCatalogs): void;
|
|
39
|
+
/** The minimal shape `registerEnabledPluginCatalogs` needs from a plugin: its
|
|
40
|
+
* id (โ `plugin:<id>` namespace) and an optional baked message fallback for
|
|
41
|
+
* when no JSON catalog was loaded (e.g. zero-dep core tooling). PluginManifest
|
|
42
|
+
* satisfies this. */
|
|
43
|
+
export interface PluginI18nSource {
|
|
44
|
+
id: string;
|
|
45
|
+
messages?: Partial<Record<string, Catalog>>;
|
|
46
|
+
}
|
|
47
|
+
/** Merge each enabled plugin's catalog under its `plugin:<id>` namespace: prefer
|
|
48
|
+
* the loaded JSON catalog, else fall back to the manifest's baked `messages`.
|
|
49
|
+
* Called by BOTH the editor and the engine so plugin chrome localizes uniformly. */
|
|
50
|
+
export declare function registerEnabledPluginCatalogs(i18n: I18n, plugins: PluginI18nSource[], loaded: LoadedCatalogs): void;
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
// Shared UI-chrome i18n runtime for the studio (editor + engine).
|
|
2
|
+
//
|
|
3
|
+
// Unlike the authored-story text i18n (see catalog.ts / project.catalogs), this
|
|
4
|
+
// localizes the *tool/game chrome*: buttons, labels, menus, toasts. It replaces
|
|
5
|
+
// the old "key-as-default" scheme (where the Chinese source string was the lookup
|
|
6
|
+
// key) with STABLE DOTTED IDs โ e.g. `topBar.home`, `cmd.bg.label`,
|
|
7
|
+
// `plugin.charfx.name`, `engine.menu.save`. Lookup falls back active โ base(en) โ
|
|
8
|
+
// the raw id, so a missing translation surfaces a visible id rather than silently
|
|
9
|
+
// showing another language.
|
|
10
|
+
//
|
|
11
|
+
// Zero-dependency and pure: no fetch/fs. Catalogs are plain data injected via
|
|
12
|
+
// registerCatalog / applyCatalogs; the fetching/globbing/override lives in the
|
|
13
|
+
// host packages' LocaleLoader implementations (which produce a LoadedCatalogs and
|
|
14
|
+
// hand it here). The editor and engine each own their own instance โ they can't
|
|
15
|
+
// share memory across the engine's IIFE boundary, but they share this code and the
|
|
16
|
+
// same JSON catalog files, which is what removes the old duplicated-key problem.
|
|
17
|
+
const PLACEHOLDER = /\{(\w+)\}/g;
|
|
18
|
+
function fill(tpl, params) {
|
|
19
|
+
return tpl.replace(PLACEHOLDER, (_, name) => (name in params ? String(params[name]) : `{${name}}`));
|
|
20
|
+
}
|
|
21
|
+
/** Create an i18n instance. `base` (default `en`) is the guaranteed-complete
|
|
22
|
+
* fallback language; `active` defaults to `base`. */
|
|
23
|
+
export function createI18n(opts) {
|
|
24
|
+
const base = opts?.base ?? 'en';
|
|
25
|
+
let active = opts?.active ?? base;
|
|
26
|
+
// Flat merged catalog per language; ids are globally unique so namespace need
|
|
27
|
+
// not be a lookup dimension.
|
|
28
|
+
const merged = {};
|
|
29
|
+
return {
|
|
30
|
+
setLocale(lang) {
|
|
31
|
+
active = lang;
|
|
32
|
+
},
|
|
33
|
+
getLocale() {
|
|
34
|
+
return active;
|
|
35
|
+
},
|
|
36
|
+
registerCatalog(_namespace, lang, catalog) {
|
|
37
|
+
Object.assign((merged[lang] ??= {}), catalog);
|
|
38
|
+
},
|
|
39
|
+
t(id, params) {
|
|
40
|
+
const tpl = merged[active]?.[id] ?? merged[base]?.[id] ?? id;
|
|
41
|
+
return params ? fill(tpl, params) : tpl;
|
|
42
|
+
},
|
|
43
|
+
has(id) {
|
|
44
|
+
return merged[active]?.[id] !== undefined || merged[base]?.[id] !== undefined;
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/** Register every namespace/language of a LoadedCatalogs into an instance. */
|
|
49
|
+
export function applyCatalogs(i18n, loaded) {
|
|
50
|
+
for (const namespace in loaded) {
|
|
51
|
+
const byLang = loaded[namespace];
|
|
52
|
+
for (const lang in byLang)
|
|
53
|
+
i18n.registerCatalog(namespace, lang, byLang[lang]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Merge each enabled plugin's catalog under its `plugin:<id>` namespace: prefer
|
|
57
|
+
* the loaded JSON catalog, else fall back to the manifest's baked `messages`.
|
|
58
|
+
* Called by BOTH the editor and the engine so plugin chrome localizes uniformly. */
|
|
59
|
+
export function registerEnabledPluginCatalogs(i18n, plugins, loaded) {
|
|
60
|
+
for (const p of plugins) {
|
|
61
|
+
const ns = `plugin:${p.id}`;
|
|
62
|
+
const fromJson = loaded[ns];
|
|
63
|
+
if (fromJson) {
|
|
64
|
+
for (const lang in fromJson)
|
|
65
|
+
i18n.registerCatalog(ns, lang, fromJson[lang]);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const baked = p.messages;
|
|
69
|
+
if (baked) {
|
|
70
|
+
for (const lang in baked) {
|
|
71
|
+
const cat = baked[lang];
|
|
72
|
+
if (cat)
|
|
73
|
+
i18n.registerCatalog(ns, lang, cat);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export * from './ir.js';
|
|
2
|
+
export * from './schema.js';
|
|
3
|
+
export * from './commands.js';
|
|
4
|
+
export * from './plugin-manifest.js';
|
|
5
|
+
export * from './semver.js';
|
|
6
|
+
export * from './plugins.js';
|
|
7
|
+
export * from './serialize.js';
|
|
8
|
+
export * from './catalog.js';
|
|
9
|
+
export * from './i18n.js';
|
|
10
|
+
export * from './chunk.js';
|
|
11
|
+
export * from './chunk-build.js';
|
|
12
|
+
export * from './package.js';
|
|
13
|
+
export * from './versions.js';
|
|
14
|
+
export * from './screenplay.js';
|
|
15
|
+
export * from './screenplay-format.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @nilvn/core โ shared document model (IR) and command schema for the creator studio.
|
|
2
|
+
// Consumed by the engine, editor, AI generation and the in-browser bundler.
|
|
3
|
+
export * from './ir.js';
|
|
4
|
+
export * from './schema.js';
|
|
5
|
+
export * from './commands.js';
|
|
6
|
+
export * from './plugin-manifest.js';
|
|
7
|
+
export * from './semver.js';
|
|
8
|
+
export * from './plugins.js';
|
|
9
|
+
export * from './serialize.js';
|
|
10
|
+
export * from './catalog.js';
|
|
11
|
+
export * from './i18n.js';
|
|
12
|
+
export * from './chunk.js';
|
|
13
|
+
export * from './chunk-build.js';
|
|
14
|
+
export * from './package.js';
|
|
15
|
+
export * from './versions.js';
|
|
16
|
+
export * from './screenplay.js';
|
|
17
|
+
export * from './screenplay-format.js';
|