@doki-land/live2d-core 0.0.13 โ†’ 0.0.15

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
@@ -1,3 +1,106 @@
1
1
  # @doki-land/live2d-core
2
2
 
3
- live2d.ts package 0.0.13.
3
+ Framework-independent contracts and data structures for the `live2d.ts` runtime.
4
+
5
+ This is an implementation package. Application developers should normally install `@doki-land/live2d` instead.
6
+
7
+ ## ๐Ÿงญ Package Role
8
+
9
+ The core package defines the shared language used by loaders, model runtimes, renderers, and the public facade:
10
+
11
+ - model sources and normalized settings;
12
+ - session phases and state;
13
+ - runtime events and progress payloads;
14
+ - model programs and instances;
15
+ - frame snapshots and drawable data;
16
+ - asset resolver contracts;
17
+ - format detection shared across packages.
18
+
19
+ It does not fetch network resources, decode MOC binaries, create a canvas, or issue GPU commands.
20
+
21
+ ## ๐Ÿ“ฆ Installation
22
+
23
+ ```bash
24
+ pnpm add @doki-land/live2d-core
25
+ ```
26
+
27
+ Install this package directly only when implementing a compatible loader, renderer, diagnostic tool, or host integration.
28
+
29
+ ## ๐Ÿงฑ Design Principles
30
+
31
+ - Contracts remain independent of game engines, blog engines, and UI frameworks.
32
+ - Graphics API types do not leak into model and session contracts.
33
+ - Model-format parsing does not belong in core.
34
+ - Public data uses explicit typed structures rather than hidden runtime globals.
35
+ - Events remain small enough for browsers and lightweight hosts.
36
+
37
+ ## ๐Ÿงฉ Core Contracts
38
+
39
+ The package exposes types such as:
40
+
41
+ ```ts
42
+ import type {
43
+ AssetResolver,
44
+ FrameSnapshot,
45
+ Live2DSession,
46
+ ModelSettings,
47
+ ModelSource,
48
+ } from "@doki-land/live2d-core";
49
+ ```
50
+
51
+ An asset resolver provides model-related resources without prescribing HTTP, file-system, CDN, or package-registry behavior:
52
+
53
+ ```ts
54
+ const resolver: AssetResolver = {
55
+ async fetchJson(url) {
56
+ const response = await fetch(url);
57
+ return response.json();
58
+ },
59
+ async fetchBytes(url) {
60
+ const response = await fetch(url);
61
+ return response.arrayBuffer();
62
+ },
63
+ };
64
+ ```
65
+
66
+ Use the exact exported interface as the source of truth; the example illustrates the ownership boundary rather than guaranteeing every method name across versions.
67
+
68
+ ## ๐Ÿ”„ Session Lifecycle
69
+
70
+ A runtime session moves through explicit phases rather than relying on DOM state:
71
+
72
+ ```text
73
+ idle -> mounting -> ready -> loading -> live
74
+ \-> error
75
+ ```
76
+
77
+ Consumers should listen to phase and error events instead of inferring readiness from a non-null canvas or model reference.
78
+
79
+ ## ๐Ÿ“ธ Frame Data
80
+
81
+ `FrameSnapshot` represents evaluated CPU-side model output. It is useful for:
82
+
83
+ - renderer input;
84
+ - deterministic fixtures;
85
+ - diagnostic capture;
86
+ - regression fingerprints;
87
+ - model inspection tools.
88
+
89
+ Frame data must not contain host-specific UI state or require a renderer to reload source assets.
90
+
91
+ ## ๐Ÿงช Development
92
+
93
+ ```bash
94
+ pnpm --filter @doki-land/live2d-core typecheck
95
+ pnpm --filter @doki-land/live2d-core test
96
+ ```
97
+
98
+ Contract changes should include compatibility notes in the change itself and update all workspace consumers in the same change set.
99
+
100
+ ## ๐Ÿค Contributing
101
+
102
+ Avoid adding convenience APIs that belong to the facade. A core abstraction should be shared by at least two implementation layers and remain meaningful without a browser UI framework.
103
+
104
+ ## ๐Ÿ“„ License
105
+
106
+ See the repository license.
package/dist/index.d.ts CHANGED
@@ -182,6 +182,24 @@ interface FrameSnapshot {
182
182
  readonly drawables: readonly FrameDrawable[];
183
183
  }
184
184
 
185
+ /**
186
+ * Read-only model resources shared across actors on one stage
187
+ * (settings, decoded topology, textures, motion definitions).
188
+ */
189
+ interface ModelAsset {
190
+ readonly key: string;
191
+ readonly settings: ModelSettings;
192
+ }
193
+ /** Stage-scoped model resource cache (`stage.assets`). */
194
+ interface Live2dStageAssets {
195
+ load(source: ModelSource, resolver?: AssetResolver): Promise<ModelAsset>;
196
+ }
197
+ /** Per-actor mutable runtime bound to a shared {@link ModelAsset}. */
198
+ interface ActorInstance {
199
+ readonly asset: ModelAsset;
200
+ readonly model: InternalModel;
201
+ }
202
+
185
203
  /**
186
204
  * CPU model program / instance shapes (format adapters fill these).
187
205
  */
@@ -300,6 +318,14 @@ type StageUpdateMode = "auto" | "manual";
300
318
  interface CreateLive2dStageOptions {
301
319
  updateMode?: StageUpdateMode;
302
320
  }
321
+ interface PlayMotionActorOptions {
322
+ priority?: number;
323
+ slot?: string;
324
+ queue?: boolean;
325
+ loop?: boolean;
326
+ fadeInTime?: number;
327
+ fadeOutTime?: number;
328
+ }
303
329
  /** Read-only actor surface exposed by the stage. */
304
330
  interface Live2dActor {
305
331
  readonly id: string;
@@ -312,17 +338,44 @@ interface Live2dActor {
312
338
  getTransform(): ActorTransform;
313
339
  setTransform(patch: Partial<ActorTransform>): void;
314
340
  load(source: ModelSource, resolver?: AssetResolver): Promise<InternalModel>;
341
+ /** Attach a stage-cached {@link ModelAsset} without re-fetching resources. */
342
+ loadAsset(asset: ModelAsset): Promise<InternalModel>;
315
343
  setParameter(id: string, value: number): void;
344
+ listParameters(): ReadonlyArray<{
345
+ id: string;
346
+ min: number;
347
+ max: number;
348
+ defaultValue: number;
349
+ value: number;
350
+ }>;
351
+ listMotionGroups(): Record<string, readonly MotionDefinition[]>;
352
+ playMotion(group: string, index?: number, options?: PlayMotionActorOptions): Promise<boolean>;
353
+ stopMotion(opts?: {
354
+ fade?: boolean;
355
+ slot?: string;
356
+ }): void;
357
+ listPlayingMotions(): ReadonlyArray<{
358
+ slot: string;
359
+ group: string;
360
+ index: number;
361
+ time: number;
362
+ priority: number;
363
+ }>;
316
364
  lookAt(stageX: number, stageY: number): void;
317
365
  destroy(): void;
318
366
  }
319
367
  /** Multi-character stage owning one canvas surface and shared renderer. */
320
368
  interface Live2dStage {
321
369
  readonly actors: readonly Live2dActor[];
370
+ /** Shared model resource cache for multi-actor reuse. */
371
+ readonly assets: Live2dStageAssets;
322
372
  mount(canvas: HTMLCanvasElement): Promise<void>;
323
373
  createActor(options?: CreateActorOptions): Live2dActor;
374
+ getActor(id: string): Live2dActor | null;
324
375
  removeActor(actor: Live2dActor | string): void;
325
376
  defineLayers(layers: readonly string[]): void;
377
+ /** Sync canvas backing store and renderer to CSS or explicit pixel size. */
378
+ resize(width?: number, height?: number): void;
326
379
  update(deltaTimeSeconds: number): void;
327
380
  render(): void;
328
381
  start(): void;
@@ -343,4 +396,4 @@ interface Live2dStage {
343
396
 
344
397
  declare const LIVE2D_CORE_VERSION: "0.0.0";
345
398
 
346
- export { type ActorHit, type ActorTransform, type AssetKey, type AssetResolver, type CreateActorOptions, type CreateLive2dStageOptions, DEFAULT_ACTOR_TRANSFORM, type DrawableProgram, EventEmitter, type ExpressionDefinition, FrameBlendMode, type FrameDrawable, type FrameProfile, type FrameSnapshot, type HitAreaDefinition, type InternalModel, LIVE2D_CORE_VERSION, type Live2DEventMap, type Live2DEventName, type Live2DListener, type Live2DSession, type Live2dActor, type Live2dStage, type LoadProgress, type LoadProgressStage, type ModelFormat, type ModelInstance, type ModelProgram, type ModelSettings, type ModelSource, type MotionDefinition, type ParameterProgram, type PointerTrackingMode, type PointerTrackingPolicy, type SessionPhase, type SessionState, type StagePointerEvent, type StageUpdateMode, createSessionStub, detectModelSettingsFormat, modelSourceUrl };
399
+ export { type ActorHit, type ActorInstance, type ActorTransform, type AssetKey, type AssetResolver, type CreateActorOptions, type CreateLive2dStageOptions, DEFAULT_ACTOR_TRANSFORM, type DrawableProgram, EventEmitter, type ExpressionDefinition, FrameBlendMode, type FrameDrawable, type FrameProfile, type FrameSnapshot, type HitAreaDefinition, type InternalModel, LIVE2D_CORE_VERSION, type Live2DEventMap, type Live2DEventName, type Live2DListener, type Live2DSession, type Live2dActor, type Live2dStage, type Live2dStageAssets, type LoadProgress, type LoadProgressStage, type ModelAsset, type ModelFormat, type ModelInstance, type ModelProgram, type ModelSettings, type ModelSource, type MotionDefinition, type ParameterProgram, type PlayMotionActorOptions, type PointerTrackingMode, type PointerTrackingPolicy, type SessionPhase, type SessionState, type StagePointerEvent, type StageUpdateMode, createSessionStub, detectModelSettingsFormat, modelSourceUrl };
package/package.json CHANGED
@@ -1,10 +1,15 @@
1
1
  {
2
2
  "name": "@doki-land/live2d-core",
3
- "version": "0.0.13",
4
- "description": "Live2D types, events, and session contracts",
3
+ "version": "0.0.15",
4
+ "description": "Shared TypeScript contracts for live2d.ts โ€” ModelSource, Live2dStage/Actor, ModelAsset, events (no DOM/GPU).",
5
5
  "type": "module",
6
6
  "license": "MIT",
7
- "author": "Doki Land",
7
+ "homepage": "https://github.com/doki-land/live2d.ts",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/doki-land/live2d.ts.git",
11
+ "directory": "projects/live2d-core"
12
+ },
8
13
  "keywords": [
9
14
  "live2d",
10
15
  "doki-land"
@@ -16,7 +21,8 @@
16
21
  },
17
22
  "files": [
18
23
  "dist",
19
- "src"
24
+ "src",
25
+ "README.md"
20
26
  ],
21
27
  "publishConfig": {
22
28
  "access": "public",
@@ -34,9 +40,5 @@
34
40
  "typecheck": "tsc --noEmit",
35
41
  "test": "vitest run --passWithNoTests"
36
42
  },
37
- "sideEffects": false,
38
- "repository": {
39
- "type": "git",
40
- "url": "git+https://github.com/doki-land/live2d.ts.git"
41
- }
43
+ "sideEffects": false
42
44
  }
package/src/index.ts CHANGED
@@ -33,6 +33,11 @@ export type {
33
33
  ModelSettings,
34
34
  MotionDefinition,
35
35
  } from "./model.js";
36
+ export type {
37
+ ActorInstance,
38
+ Live2dStageAssets,
39
+ ModelAsset,
40
+ } from "./model-asset.js";
36
41
  export type {
37
42
  DrawableProgram,
38
43
  ModelInstance,
@@ -50,6 +55,7 @@ export type {
50
55
  CreateLive2dStageOptions,
51
56
  Live2dActor,
52
57
  Live2dStage,
58
+ PlayMotionActorOptions,
53
59
  PointerTrackingMode,
54
60
  PointerTrackingPolicy,
55
61
  StagePointerEvent,
@@ -0,0 +1,22 @@
1
+ import type { AssetResolver, ModelSource } from "./contracts.js";
2
+ import type { InternalModel, ModelSettings } from "./model.js";
3
+
4
+ /**
5
+ * Read-only model resources shared across actors on one stage
6
+ * (settings, decoded topology, textures, motion definitions).
7
+ */
8
+ export interface ModelAsset {
9
+ readonly key: string;
10
+ readonly settings: ModelSettings;
11
+ }
12
+
13
+ /** Stage-scoped model resource cache (`stage.assets`). */
14
+ export interface Live2dStageAssets {
15
+ load(source: ModelSource, resolver?: AssetResolver): Promise<ModelAsset>;
16
+ }
17
+
18
+ /** Per-actor mutable runtime bound to a shared {@link ModelAsset}. */
19
+ export interface ActorInstance {
20
+ readonly asset: ModelAsset;
21
+ readonly model: InternalModel;
22
+ }
package/src/stage.ts CHANGED
@@ -1,4 +1,6 @@
1
- import type { InternalModel } from "./model.js";
1
+ import type { AssetResolver, ModelSource } from "./contracts.js";
2
+ import type { InternalModel, MotionDefinition } from "./model.js";
3
+ import type { ModelAsset } from "./model-asset.js";
2
4
 
3
5
  /** Normalized stage placement for one actor (0,0) top-left โ†’ (1,1) bottom-right. */
4
6
  export interface ActorTransform {
@@ -77,6 +79,15 @@ export interface CreateLive2dStageOptions {
77
79
  updateMode?: StageUpdateMode;
78
80
  }
79
81
 
82
+ export interface PlayMotionActorOptions {
83
+ priority?: number;
84
+ slot?: string;
85
+ queue?: boolean;
86
+ loop?: boolean;
87
+ fadeInTime?: number;
88
+ fadeOutTime?: number;
89
+ }
90
+
80
91
  /** Read-only actor surface exposed by the stage. */
81
92
  export interface Live2dActor {
82
93
  readonly id: string;
@@ -91,13 +102,39 @@ export interface Live2dActor {
91
102
 
92
103
  setTransform(patch: Partial<ActorTransform>): void;
93
104
 
94
- load(
95
- source: import("./contracts.js").ModelSource,
96
- resolver?: import("./contracts.js").AssetResolver,
97
- ): Promise<InternalModel>;
105
+ load(source: ModelSource, resolver?: AssetResolver): Promise<InternalModel>;
106
+
107
+ /** Attach a stage-cached {@link ModelAsset} without re-fetching resources. */
108
+ loadAsset(asset: ModelAsset): Promise<InternalModel>;
98
109
 
99
110
  setParameter(id: string, value: number): void;
100
111
 
112
+ listParameters(): ReadonlyArray<{
113
+ id: string;
114
+ min: number;
115
+ max: number;
116
+ defaultValue: number;
117
+ value: number;
118
+ }>;
119
+
120
+ listMotionGroups(): Record<string, readonly MotionDefinition[]>;
121
+
122
+ playMotion(
123
+ group: string,
124
+ index?: number,
125
+ options?: PlayMotionActorOptions,
126
+ ): Promise<boolean>;
127
+
128
+ stopMotion(opts?: { fade?: boolean; slot?: string }): void;
129
+
130
+ listPlayingMotions(): ReadonlyArray<{
131
+ slot: string;
132
+ group: string;
133
+ index: number;
134
+ time: number;
135
+ priority: number;
136
+ }>;
137
+
101
138
  lookAt(stageX: number, stageY: number): void;
102
139
 
103
140
  destroy(): void;
@@ -107,14 +144,22 @@ export interface Live2dActor {
107
144
  export interface Live2dStage {
108
145
  readonly actors: readonly Live2dActor[];
109
146
 
147
+ /** Shared model resource cache for multi-actor reuse. */
148
+ readonly assets: import("./model-asset.js").Live2dStageAssets;
149
+
110
150
  mount(canvas: HTMLCanvasElement): Promise<void>;
111
151
 
112
152
  createActor(options?: CreateActorOptions): Live2dActor;
113
153
 
154
+ getActor(id: string): Live2dActor | null;
155
+
114
156
  removeActor(actor: Live2dActor | string): void;
115
157
 
116
158
  defineLayers(layers: readonly string[]): void;
117
159
 
160
+ /** Sync canvas backing store and renderer to CSS or explicit pixel size. */
161
+ resize(width?: number, height?: number): void;
162
+
118
163
  update(deltaTimeSeconds: number): void;
119
164
 
120
165
  render(): void;