@ksgames26/core 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("./index2.cjs"),r=require("./index3.cjs"),o=require("./index4.cjs"),a=require("./index5.cjs"),e=require("./index6.cjs"),c=require("./index7.cjs"),n=require("./index8.cjs"),l=require("./index9.cjs");exports.GameApplication=t.GameApplication;exports.Module=r.Module;exports.detectPlatformName=o.detectPlatformName;exports.WebAdapter=a.WebAdapter;exports.EventBus=e.EventBus;exports.GameEvents=e.GameEvents;exports.ScreenAdapter=c.ScreenAdapter;exports.ObjectPool=n.ObjectPool;exports.DefaultDisplayObjectFactory=l.DefaultDisplayObjectFactory;
2
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -0,0 +1,410 @@
1
+ import { Application } from 'pixi.js';
2
+ import { BitmapText } from 'pixi.js';
3
+ import { Container } from 'pixi.js';
4
+ import { Graphics } from 'pixi.js';
5
+ import { Sprite } from 'pixi.js';
6
+ import { Text as Text_2 } from 'pixi.js';
7
+ import { TextOptions } from 'pixi.js';
8
+ import { Texture } from 'pixi.js';
9
+
10
+ /**
11
+ * Default factory implementation that directly calls PixiJS constructors.
12
+ */
13
+ export declare class DefaultDisplayObjectFactory implements DisplayObjectFactory {
14
+ createSprite(texture?: Texture): Sprite;
15
+ createContainer(): Container;
16
+ createGraphics(): Graphics;
17
+ createBitmapText(fontName: string, text: string): BitmapText;
18
+ createText(options: TextOptions): Text_2;
19
+ }
20
+
21
+ /**
22
+ * Auto-detect current platform and return appropriate adapter name.
23
+ * Detection order: wx → tt → web
24
+ */
25
+ export declare function detectPlatformName(): 'wechat' | 'douyin' | 'web';
26
+
27
+ /**
28
+ * Display object factory interface.
29
+ * Satisfies Constitution VI: "Display object creation MUST go through
30
+ * factory functions, making it easy to replace with Mocks in tests."
31
+ */
32
+ export declare interface DisplayObjectFactory {
33
+ /** Create a sprite */
34
+ createSprite(texture?: Texture): Sprite;
35
+ /** Create a container */
36
+ createContainer(): Container;
37
+ /** Create a graphics object */
38
+ createGraphics(): Graphics;
39
+ /**
40
+ * Create a bitmap text (default text approach).
41
+ * Satisfies Constitution IV: "Text rendering MUST use BitmapText
42
+ * or pre-rendering strategy."
43
+ */
44
+ createBitmapText(fontName: string, text: string): BitmapText;
45
+ /**
46
+ * Create a dynamic text (for multilingual or runtime-rendered text).
47
+ * Only use when BitmapText is not suitable.
48
+ */
49
+ createText(options: TextOptions): Text_2;
50
+ }
51
+
52
+ /**
53
+ * Typed event bus for framework communication.
54
+ * Modules MUST communicate through events, never by direct state access.
55
+ */
56
+ export declare class EventBus {
57
+ private handlers;
58
+ /**
59
+ * Subscribe to an event.
60
+ * @returns Unsubscribe function
61
+ */
62
+ on(event: string, handler: EventHandler): () => void;
63
+ /**
64
+ * Subscribe to an event once. Auto-removes after first invocation.
65
+ */
66
+ once(event: string, handler: EventHandler): () => void;
67
+ /**
68
+ * Unsubscribe from an event.
69
+ */
70
+ off(event: string, handler: EventHandler): void;
71
+ /**
72
+ * Emit an event to all subscribers.
73
+ */
74
+ emit(event: string, ...args: unknown[]): void;
75
+ /**
76
+ * Remove all handlers for a specific event, or all events.
77
+ */
78
+ clear(event?: string): void;
79
+ }
80
+
81
+ declare type EventHandler = (...args: unknown[]) => void;
82
+
83
+ /**
84
+ * Framework main entry point.
85
+ * Initializes the PixiJS renderer and coordinates all modules.
86
+ */
87
+ export declare class GameApplication {
88
+ /** PixiJS Application instance */
89
+ readonly pixiApp: Application;
90
+ /** Event bus for module communication */
91
+ readonly events: EventBus;
92
+ /** Display object factory (Constitution VI) */
93
+ readonly factory: DisplayObjectFactory;
94
+ /** Registered modules */
95
+ private modules;
96
+ /** Platform adapter */
97
+ private _platform;
98
+ /** Screen adapter */
99
+ private _screen;
100
+ /** Framework config */
101
+ private _config;
102
+ /** Whether in development mode */
103
+ isDev: boolean;
104
+ /** Get framework configuration (read-only) */
105
+ get config(): Readonly<GameConfig>;
106
+ /** Application state */
107
+ private state;
108
+ constructor(factory?: DisplayObjectFactory);
109
+ /**
110
+ * Initialize the framework with configuration.
111
+ * Creates PixiJS Application, selects platform adapter, and enables modules.
112
+ */
113
+ init(config?: GameConfig): Promise<this>;
114
+ /**
115
+ * Register a module with the framework.
116
+ */
117
+ registerModule(module: Module): this;
118
+ /**
119
+ * Get a registered module by name.
120
+ */
121
+ getModule<T extends Module>(name: string): T | undefined;
122
+ /**
123
+ * Get the platform adapter.
124
+ */
125
+ get platform(): PlatformAdapter;
126
+ /**
127
+ * Get the screen adapter.
128
+ */
129
+ get screen(): ScreenAdapter;
130
+ /**
131
+ * Destroy the framework and release all resources.
132
+ * Order: scenes → modules → assets → renderer
133
+ */
134
+ destroy(): void;
135
+ /**
136
+ * Setup platform adapter based on config or auto-detection.
137
+ * For mini-game platforms (WeChat/Douyin), user must provide adapter instance
138
+ * since dynamic imports are not supported in mini-game environments.
139
+ */
140
+ private setupPlatform;
141
+ /**
142
+ * Register WebGL context loss handling with auto-recovery.
143
+ * PixiJS v8 handles the actual recovery; we emit events for business logic.
144
+ */
145
+ private setupContextLossHandling;
146
+ /**
147
+ * Enable all registered modules.
148
+ */
149
+ private enableModules;
150
+ }
151
+
152
+ /**
153
+ * Framework initialization configuration.
154
+ */
155
+ export declare interface GameConfig {
156
+ /** Canvas width, defaults to window.innerWidth */
157
+ width?: number;
158
+ /** Canvas height, defaults to window.innerHeight */
159
+ height?: number;
160
+ /** Background color, defaults to 0x000000 */
161
+ backgroundColor?: number;
162
+ /** Render resolution, defaults to devicePixelRatio */
163
+ resolution?: number;
164
+ /** Antialiasing, defaults to true */
165
+ antialias?: boolean;
166
+ /** Target platform, defaults to 'auto' (auto-detect) */
167
+ platform?: 'web' | 'wechat' | 'douyin' | 'auto';
168
+ /** Platform adapter instance. Required for mini-game platforms (WeChat/Douyin) */
169
+ platformAdapter?: PlatformAdapter;
170
+ /** Development debug mode, defaults to false */
171
+ debug?: boolean;
172
+ /** Modules that must NOT be tree-shaken even if unreferenced */
173
+ noStripModules?: string[];
174
+ }
175
+
176
+ export declare type GameEventName = (typeof GameEvents)[keyof typeof GameEvents];
177
+
178
+ /**
179
+ * Framework event name constants.
180
+ */
181
+ export declare const GameEvents: {
182
+ readonly APP_INIT: "app:init";
183
+ readonly APP_CONTEXT_LOST: "app:contextlost";
184
+ readonly APP_CONTEXT_RESTORED: "app:contextrestored";
185
+ readonly APP_RENDERER_FALLBACK: "app:rendererfallback";
186
+ readonly SCREEN_RESIZE: "screen:resize";
187
+ readonly SCENE_SWITCH: "scene:switch";
188
+ readonly SCENE_SWITCHED: "scene:switched";
189
+ readonly ASSET_LOADED: "asset:loaded";
190
+ readonly ASSET_UNLOADED: "asset:unloaded";
191
+ readonly ASSET_ERROR: "asset:error";
192
+ };
193
+
194
+ /**
195
+ * Abstract base class for framework modules.
196
+ * Each module is an independent npm package, loaded via tree-shaking.
197
+ */
198
+ export declare abstract class Module {
199
+ /** Module unique identifier */
200
+ abstract readonly name: string;
201
+ /** Module version */
202
+ abstract readonly version: string;
203
+ /** Framework instance reference (injected on register) */
204
+ protected app: GameApplication;
205
+ /** Whether the module is enabled */
206
+ enabled: boolean;
207
+ /**
208
+ * Called when the module is registered with the framework.
209
+ * Receives the GameApplication instance for dependency injection.
210
+ */
211
+ onRegister(_app: GameApplication): void;
212
+ /**
213
+ * Enable the module. Can be async to support resource loading.
214
+ */
215
+ onEnable(): Promise<void>;
216
+ /**
217
+ * Disable the module.
218
+ */
219
+ onDisable(): void;
220
+ /**
221
+ * Destroy the module and release all resources.
222
+ */
223
+ onDestroy(): void;
224
+ }
225
+
226
+ /**
227
+ * Generic object pool for frequently created/destroyed display objects.
228
+ * Satisfies Constitution I: "Object Pool MUST be used for frequently
229
+ * created/destroyed display objects (particles, bullets, effects)."
230
+ *
231
+ * Pure logic - no platform API dependencies.
232
+ */
233
+ export declare class ObjectPool<T> {
234
+ private pool;
235
+ private factory;
236
+ private reset;
237
+ private active;
238
+ /**
239
+ * @param factory Function to create a new object
240
+ * @param reset Function to reset an object when returned to pool
241
+ * @param initialSize Number of objects to pre-create
242
+ */
243
+ constructor(factory: () => T, reset: (obj: T) => void, initialSize?: number);
244
+ /**
245
+ * Number of objects available in the pool.
246
+ */
247
+ get size(): number;
248
+ /**
249
+ * Number of currently active (borrowed) objects.
250
+ */
251
+ get activeCount(): number;
252
+ /**
253
+ * Acquire an object from the pool.
254
+ * Creates a new one if the pool is empty.
255
+ */
256
+ acquire(): T;
257
+ /**
258
+ * Release an object back to the pool.
259
+ * The reset function is called to prepare the object for reuse.
260
+ */
261
+ release(obj: T): void;
262
+ /**
263
+ * Pre-warm the pool by creating objects upfront.
264
+ * Useful to avoid allocation spikes at runtime.
265
+ */
266
+ prewarm(count: number): void;
267
+ /**
268
+ * Drain all objects from the pool.
269
+ */
270
+ drain(): void;
271
+ }
272
+
273
+ /**
274
+ * Platform adapter interface.
275
+ * Abstracts platform differences for canvas, storage, network, and input.
276
+ */
277
+ export declare interface PlatformAdapter {
278
+ /** Create the main canvas element */
279
+ createCanvas(): HTMLCanvasElement;
280
+ /** Create an image element */
281
+ createImage(): HTMLImageElement;
282
+ /** Get local storage implementation */
283
+ getStorage(): StorageLike;
284
+ /** Register a frame callback */
285
+ requestAnimationFrame(callback: FrameRequestCallback): number;
286
+ /** Cancel a frame callback */
287
+ cancelAnimationFrame(id: number): void;
288
+ /** HTTP request (fetch-compatible) */
289
+ fetch(url: string, init?: RequestInit): Promise<Response>;
290
+ /** Resolve an asset path to platform-specific format */
291
+ resolvePath(path: string): string;
292
+ /** Get system information */
293
+ getSystemInfo(): SystemInfo;
294
+ /**
295
+ * Register a callback for window/canvas resize events.
296
+ * Uses platform-native resize events (zero polling overhead).
297
+ * @returns Unsubscribe function to remove the callback
298
+ */
299
+ onResize(callback: (width: number, height: number) => void): () => void;
300
+ /** Register touch start handler */
301
+ onTouchStart(callback: (event: TouchEvent) => void): void;
302
+ /** Register touch move handler */
303
+ onTouchMove(callback: (event: TouchEvent) => void): void;
304
+ /** Register touch end handler */
305
+ onTouchEnd(callback: (event: TouchEvent) => void): void;
306
+ }
307
+
308
+ /**
309
+ * Responsive screen adapter.
310
+ * Uses PlatformAdapter.onResize() for event-driven resize detection (zero polling).
311
+ * Emits 'screen:resize' via EventBus when canvas dimensions change.
312
+ */
313
+ export declare class ScreenAdapter {
314
+ private app;
315
+ private platform;
316
+ private events;
317
+ private unsubscribe;
318
+ private lastWidth;
319
+ private lastHeight;
320
+ constructor(app: Application, platform: PlatformAdapter, events: EventBus);
321
+ /**
322
+ * Start listening for resize events via PlatformAdapter.onResize().
323
+ * Event-driven: no ticker polling, zero overhead when idle.
324
+ */
325
+ start(): void;
326
+ /**
327
+ * Stop listening for resize events.
328
+ */
329
+ stop(): void;
330
+ /**
331
+ * Handle resize: update renderer and emit event.
332
+ */
333
+ private handleResize;
334
+ /**
335
+ * Get current screen dimensions.
336
+ */
337
+ get dimensions(): {
338
+ width: number;
339
+ height: number;
340
+ };
341
+ }
342
+
343
+ /**
344
+ * Serializable state interface.
345
+ * Satisfies Constitution VI: "State management MUST use serializable
346
+ * data structures to support snapshot comparison testing."
347
+ *
348
+ * Pure logic - no platform API dependencies.
349
+ */
350
+ export declare interface SerializableState {
351
+ /**
352
+ * Serialize state to a plain JSON object.
353
+ * Return value MUST only contain JSON-compatible types:
354
+ * string, number, boolean, null, array, plain object.
355
+ */
356
+ toJSON(): Record<string, unknown>;
357
+ /**
358
+ * Restore state from a plain JSON object.
359
+ * @param data Data produced by toJSON()
360
+ */
361
+ fromJSON(data: Record<string, unknown>): void;
362
+ /**
363
+ * Create a read-only snapshot of current state.
364
+ * Used for state comparison testing and debugging.
365
+ */
366
+ snapshot(): Readonly<Record<string, unknown>>;
367
+ }
368
+
369
+ /**
370
+ * Minimal storage interface compatible with localStorage and mini-game APIs.
371
+ */
372
+ export declare interface StorageLike {
373
+ getItem(key: string): string | null;
374
+ setItem(key: string, value: string): void;
375
+ removeItem(key: string): void;
376
+ clear(): void;
377
+ }
378
+
379
+ /**
380
+ * System information returned by platform adapter.
381
+ */
382
+ export declare interface SystemInfo {
383
+ screenWidth: number;
384
+ screenHeight: number;
385
+ pixelRatio: number;
386
+ platform: 'web' | 'wechat' | 'douyin';
387
+ systemVersion: string;
388
+ }
389
+
390
+ /**
391
+ * Web platform adapter.
392
+ * Uses standard browser APIs.
393
+ * Included in core package to avoid dynamic imports (mini-game compatibility).
394
+ */
395
+ export declare class WebAdapter implements PlatformAdapter {
396
+ createCanvas(): HTMLCanvasElement;
397
+ createImage(): HTMLImageElement;
398
+ getStorage(): StorageLike;
399
+ requestAnimationFrame(callback: FrameRequestCallback): number;
400
+ cancelAnimationFrame(id: number): void;
401
+ fetch(url: string, init?: RequestInit): Promise<Response>;
402
+ resolvePath(path: string): string;
403
+ getSystemInfo(): SystemInfo;
404
+ onResize(callback: (width: number, height: number) => void): () => void;
405
+ onTouchStart(callback: (event: TouchEvent) => void): void;
406
+ onTouchMove(callback: (event: TouchEvent) => void): void;
407
+ onTouchEnd(callback: (event: TouchEvent) => void): void;
408
+ }
409
+
410
+ export { }
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ import { GameApplication as r } from "./index2.js";
2
+ import { Module as p } from "./index3.js";
3
+ import { detectPlatformName as a } from "./index4.js";
4
+ import { WebAdapter as x } from "./index5.js";
5
+ import { EventBus as l, GameEvents as d } from "./index6.js";
6
+ import { ScreenAdapter as b } from "./index7.js";
7
+ import { ObjectPool as s } from "./index8.js";
8
+ import { DefaultDisplayObjectFactory as A } from "./index9.js";
9
+ export {
10
+ A as DefaultDisplayObjectFactory,
11
+ l as EventBus,
12
+ r as GameApplication,
13
+ d as GameEvents,
14
+ p as Module,
15
+ s as ObjectPool,
16
+ b as ScreenAdapter,
17
+ x as WebAdapter,
18
+ a as detectPlatformName
19
+ };
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,2 @@
1
+ "use strict";var o=Object.defineProperty;var p=(i,t,e)=>t in i?o(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var s=(i,t,e)=>p(i,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("pixi.js"),r=require("./index6.cjs"),h=require("./index4.cjs"),c=require("./index5.cjs"),d=require("./index7.cjs"),u=require("./index9.cjs");class m{constructor(t){s(this,"pixiApp");s(this,"events",new r.EventBus);s(this,"factory");s(this,"modules",new Map);s(this,"_platform");s(this,"_screen");s(this,"_config",{});s(this,"isDev",!1);s(this,"state","idle");this.pixiApp=new l.Application,this.factory=t??new u.DefaultDisplayObjectFactory}get config(){return this._config}async init(t={}){if(this.state!=="idle")throw new Error(`[GameApplication] Cannot init in state "${this.state}"`);this.state="initializing",this._config=t,this.isDev=t.debug??!1,await this.setupPlatform(t.platform??"auto");const e=this._platform.getSystemInfo();return await this.pixiApp.init({width:t.width??e.screenWidth,height:t.height??e.screenHeight,backgroundColor:t.backgroundColor??0,resolution:t.resolution??e.pixelRatio,antialias:t.antialias??!0,autoDensity:!0,preference:"webgl"}),this._screen=new d.ScreenAdapter(this.pixiApp,this._platform,this.events),this._screen.start(),this.setupContextLossHandling(),await this.enableModules(),this.state="running",this.events.emit(r.GameEvents.APP_INIT),this}registerModule(t){if(this.modules.has(t.name))throw new Error(`[GameApplication] Module "${t.name}" is already registered`);return t.onRegister(this),this.modules.set(t.name,t),this}getModule(t){return this.modules.get(t)}get platform(){return this._platform}get screen(){return this._screen}destroy(){var e;if(this.state==="destroyed"||this.state==="destroying")return;this.state="destroying";const t=[...this.modules.keys()].reverse();for(const n of t){const a=this.modules.get(n);a.onDisable(),a.onDestroy()}this.modules.clear(),(e=this._screen)==null||e.stop(),this.pixiApp.destroy(!0),this.events.clear(),this.state="destroyed"}setupPlatform(t){if(this._config.platformAdapter){this._platform=this._config.platformAdapter;return}const e=t==="auto"?h.detectPlatformName():t;switch(e){case"wechat":case"douyin":throw new Error(`[GameApplication] Platform "${e}" requires explicit adapter. Please import and pass it via config.platformAdapter. Example: import { ${e==="wechat"?"WechatAdapter":"DouyinAdapter"} } from '@ksgames26/platform-${e}'; init({ platformAdapter: new ${e==="wechat"?"WechatAdapter":"DouyinAdapter"}() })`);case"web":default:this._platform=new c.WebAdapter;break}}setupContextLossHandling(){const t=this.pixiApp.renderer;t.on("contextlost",()=>{this.events.emit(r.GameEvents.APP_CONTEXT_LOST)}),t.on("contextrestored",()=>{this.events.emit(r.GameEvents.APP_CONTEXT_RESTORED)})}async enableModules(){for(const t of this.modules.values())await t.onEnable()}}exports.GameApplication=m;
2
+ //# sourceMappingURL=index2.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index2.cjs","sources":["../src/application.ts"],"sourcesContent":["import { Application } from 'pixi.js';\nimport type { GameConfig } from './config';\nimport { EventBus, GameEvents } from './events';\nimport { Module } from './module';\nimport type { PlatformAdapter } from './platform';\nimport { detectPlatformName } from './platform';\nimport { WebAdapter } from './platform-web-adapter';\nimport { ScreenAdapter } from './screen';\nimport type { DisplayObjectFactory } from './factory';\nimport { DefaultDisplayObjectFactory } from './factory';\n\n/**\n * Framework main entry point.\n * Initializes the PixiJS renderer and coordinates all modules.\n */\nexport class GameApplication {\n /** PixiJS Application instance */\n readonly pixiApp: Application;\n\n /** Event bus for module communication */\n readonly events = new EventBus();\n\n /** Display object factory (Constitution VI) */\n readonly factory: DisplayObjectFactory;\n\n /** Registered modules */\n private modules = new Map<string, Module>();\n\n /** Platform adapter */\n private _platform!: PlatformAdapter;\n\n /** Screen adapter */\n private _screen!: ScreenAdapter;\n\n /** Framework config */\n private _config: GameConfig = {};\n\n /** Whether in development mode */\n isDev = false;\n\n /** Get framework configuration (read-only) */\n get config(): Readonly<GameConfig> {\n return this._config;\n }\n\n /** Application state */\n private state: 'idle' | 'initializing' | 'running' | 'destroying' | 'destroyed' = 'idle';\n\n constructor(factory?: DisplayObjectFactory) {\n this.pixiApp = new Application();\n this.factory = factory ?? new DefaultDisplayObjectFactory();\n }\n\n /**\n * Initialize the framework with configuration.\n * Creates PixiJS Application, selects platform adapter, and enables modules.\n */\n async init(config: GameConfig = {}): Promise<this> {\n if (this.state !== 'idle') {\n throw new Error(`[GameApplication] Cannot init in state \"${this.state}\"`);\n }\n\n this.state = 'initializing';\n this._config = config;\n this.isDev = config.debug ?? false;\n\n // Setup platform adapter first to access system info\n await this.setupPlatform(config.platform ?? 'auto');\n\n // Get screen info from platform adapter (cross-platform compatible)\n const sysInfo = this._platform.getSystemInfo();\n\n // Initialize PixiJS v8 Application (async)\n await this.pixiApp.init({\n width: config.width ?? sysInfo.screenWidth,\n height: config.height ?? sysInfo.screenHeight,\n backgroundColor: config.backgroundColor ?? 0x000000,\n resolution: config.resolution ?? sysInfo.pixelRatio,\n antialias: config.antialias ?? true,\n autoDensity: true,\n preference: 'webgl',\n });\n\n // Setup screen adapter (event-driven resize via PlatformAdapter.onResize)\n this._screen = new ScreenAdapter(this.pixiApp, this._platform, this.events);\n this._screen.start();\n\n // Register WebGL context loss handlers\n this.setupContextLossHandling();\n\n // Enable all registered modules\n await this.enableModules();\n\n this.state = 'running';\n this.events.emit(GameEvents.APP_INIT);\n return this;\n }\n\n /**\n * Register a module with the framework.\n */\n registerModule(module: Module): this {\n if (this.modules.has(module.name)) {\n throw new Error(`[GameApplication] Module \"${module.name}\" is already registered`);\n }\n module.onRegister(this);\n this.modules.set(module.name, module);\n return this;\n }\n\n /**\n * Get a registered module by name.\n */\n getModule<T extends Module>(name: string): T | undefined {\n return this.modules.get(name) as T | undefined;\n }\n\n /**\n * Get the platform adapter.\n */\n get platform(): PlatformAdapter {\n return this._platform;\n }\n\n /**\n * Get the screen adapter.\n */\n get screen(): ScreenAdapter {\n return this._screen;\n }\n\n /**\n * Destroy the framework and release all resources.\n * Order: scenes → modules → assets → renderer\n */\n destroy(): void {\n if (this.state === 'destroyed' || this.state === 'destroying') return;\n\n this.state = 'destroying';\n\n // Destroy modules in reverse order\n const moduleNames = [...this.modules.keys()].reverse();\n for (const name of moduleNames) {\n const mod = this.modules.get(name)!;\n mod.onDisable();\n mod.onDestroy();\n }\n this.modules.clear();\n\n // Stop screen adapter\n this._screen?.stop();\n\n // Destroy PixiJS application\n this.pixiApp.destroy(true);\n this.events.clear();\n\n this.state = 'destroyed';\n }\n\n /**\n * Setup platform adapter based on config or auto-detection.\n * For mini-game platforms (WeChat/Douyin), user must provide adapter instance\n * since dynamic imports are not supported in mini-game environments.\n */\n private setupPlatform(platformName: string): void {\n // Use provided adapter if available\n if (this._config.platformAdapter) {\n this._platform = this._config.platformAdapter;\n return;\n }\n\n const detected = platformName === 'auto' ? detectPlatformName() : platformName;\n\n switch (detected) {\n case 'wechat':\n case 'douyin':\n throw new Error(\n `[GameApplication] Platform \"${detected}\" requires explicit adapter. ` +\n `Please import and pass it via config.platformAdapter. ` +\n `Example: import { ${detected === 'wechat' ? 'WechatAdapter' : 'DouyinAdapter'} } from ` +\n `'@ksgames26/platform-${detected}'; init({ platformAdapter: new ${detected === 'wechat' ? 'WechatAdapter' : 'DouyinAdapter'}() })`\n );\n case 'web':\n default:\n this._platform = new WebAdapter();\n break;\n }\n }\n\n /**\n * Register WebGL context loss handling with auto-recovery.\n * PixiJS v8 handles the actual recovery; we emit events for business logic.\n */\n private setupContextLossHandling(): void {\n const renderer = this.pixiApp.renderer as unknown as {\n on(event: string, handler: () => void): void;\n };\n\n renderer.on('contextlost', () => {\n this.events.emit(GameEvents.APP_CONTEXT_LOST);\n });\n\n renderer.on('contextrestored', () => {\n this.events.emit(GameEvents.APP_CONTEXT_RESTORED);\n });\n }\n\n /**\n * Enable all registered modules.\n */\n private async enableModules(): Promise<void> {\n for (const mod of this.modules.values()) {\n await mod.onEnable();\n }\n }\n}\n"],"names":["GameApplication","factory","__publicField","EventBus","Application","DefaultDisplayObjectFactory","config","sysInfo","ScreenAdapter","GameEvents","module","name","moduleNames","mod","_a","platformName","detected","detectPlatformName","WebAdapter","renderer"],"mappings":"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"}
package/dist/index2.js ADDED
@@ -0,0 +1,142 @@
1
+ var n = Object.defineProperty;
2
+ var p = (i, t, e) => t in i ? n(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
+ var s = (i, t, e) => p(i, typeof t != "symbol" ? t + "" : t, e);
4
+ import { Application as h } from "pixi.js";
5
+ import { EventBus as l, GameEvents as r } from "./index6.js";
6
+ import { detectPlatformName as m } from "./index4.js";
7
+ import { WebAdapter as d } from "./index5.js";
8
+ import { ScreenAdapter as c } from "./index7.js";
9
+ import { DefaultDisplayObjectFactory as u } from "./index9.js";
10
+ class v {
11
+ constructor(t) {
12
+ /** PixiJS Application instance */
13
+ s(this, "pixiApp");
14
+ /** Event bus for module communication */
15
+ s(this, "events", new l());
16
+ /** Display object factory (Constitution VI) */
17
+ s(this, "factory");
18
+ /** Registered modules */
19
+ s(this, "modules", /* @__PURE__ */ new Map());
20
+ /** Platform adapter */
21
+ s(this, "_platform");
22
+ /** Screen adapter */
23
+ s(this, "_screen");
24
+ /** Framework config */
25
+ s(this, "_config", {});
26
+ /** Whether in development mode */
27
+ s(this, "isDev", !1);
28
+ /** Application state */
29
+ s(this, "state", "idle");
30
+ this.pixiApp = new h(), this.factory = t ?? new u();
31
+ }
32
+ /** Get framework configuration (read-only) */
33
+ get config() {
34
+ return this._config;
35
+ }
36
+ /**
37
+ * Initialize the framework with configuration.
38
+ * Creates PixiJS Application, selects platform adapter, and enables modules.
39
+ */
40
+ async init(t = {}) {
41
+ if (this.state !== "idle")
42
+ throw new Error(`[GameApplication] Cannot init in state "${this.state}"`);
43
+ this.state = "initializing", this._config = t, this.isDev = t.debug ?? !1, await this.setupPlatform(t.platform ?? "auto");
44
+ const e = this._platform.getSystemInfo();
45
+ return await this.pixiApp.init({
46
+ width: t.width ?? e.screenWidth,
47
+ height: t.height ?? e.screenHeight,
48
+ backgroundColor: t.backgroundColor ?? 0,
49
+ resolution: t.resolution ?? e.pixelRatio,
50
+ antialias: t.antialias ?? !0,
51
+ autoDensity: !0,
52
+ preference: "webgl"
53
+ }), this._screen = new c(this.pixiApp, this._platform, this.events), this._screen.start(), this.setupContextLossHandling(), await this.enableModules(), this.state = "running", this.events.emit(r.APP_INIT), this;
54
+ }
55
+ /**
56
+ * Register a module with the framework.
57
+ */
58
+ registerModule(t) {
59
+ if (this.modules.has(t.name))
60
+ throw new Error(`[GameApplication] Module "${t.name}" is already registered`);
61
+ return t.onRegister(this), this.modules.set(t.name, t), this;
62
+ }
63
+ /**
64
+ * Get a registered module by name.
65
+ */
66
+ getModule(t) {
67
+ return this.modules.get(t);
68
+ }
69
+ /**
70
+ * Get the platform adapter.
71
+ */
72
+ get platform() {
73
+ return this._platform;
74
+ }
75
+ /**
76
+ * Get the screen adapter.
77
+ */
78
+ get screen() {
79
+ return this._screen;
80
+ }
81
+ /**
82
+ * Destroy the framework and release all resources.
83
+ * Order: scenes → modules → assets → renderer
84
+ */
85
+ destroy() {
86
+ var e;
87
+ if (this.state === "destroyed" || this.state === "destroying") return;
88
+ this.state = "destroying";
89
+ const t = [...this.modules.keys()].reverse();
90
+ for (const o of t) {
91
+ const a = this.modules.get(o);
92
+ a.onDisable(), a.onDestroy();
93
+ }
94
+ this.modules.clear(), (e = this._screen) == null || e.stop(), this.pixiApp.destroy(!0), this.events.clear(), this.state = "destroyed";
95
+ }
96
+ /**
97
+ * Setup platform adapter based on config or auto-detection.
98
+ * For mini-game platforms (WeChat/Douyin), user must provide adapter instance
99
+ * since dynamic imports are not supported in mini-game environments.
100
+ */
101
+ setupPlatform(t) {
102
+ if (this._config.platformAdapter) {
103
+ this._platform = this._config.platformAdapter;
104
+ return;
105
+ }
106
+ const e = t === "auto" ? m() : t;
107
+ switch (e) {
108
+ case "wechat":
109
+ case "douyin":
110
+ throw new Error(
111
+ `[GameApplication] Platform "${e}" requires explicit adapter. Please import and pass it via config.platformAdapter. Example: import { ${e === "wechat" ? "WechatAdapter" : "DouyinAdapter"} } from '@ksgames26/platform-${e}'; init({ platformAdapter: new ${e === "wechat" ? "WechatAdapter" : "DouyinAdapter"}() })`
112
+ );
113
+ case "web":
114
+ default:
115
+ this._platform = new d();
116
+ break;
117
+ }
118
+ }
119
+ /**
120
+ * Register WebGL context loss handling with auto-recovery.
121
+ * PixiJS v8 handles the actual recovery; we emit events for business logic.
122
+ */
123
+ setupContextLossHandling() {
124
+ const t = this.pixiApp.renderer;
125
+ t.on("contextlost", () => {
126
+ this.events.emit(r.APP_CONTEXT_LOST);
127
+ }), t.on("contextrestored", () => {
128
+ this.events.emit(r.APP_CONTEXT_RESTORED);
129
+ });
130
+ }
131
+ /**
132
+ * Enable all registered modules.
133
+ */
134
+ async enableModules() {
135
+ for (const t of this.modules.values())
136
+ await t.onEnable();
137
+ }
138
+ }
139
+ export {
140
+ v as GameApplication
141
+ };
142
+ //# sourceMappingURL=index2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index2.js","sources":["../src/application.ts"],"sourcesContent":["import { Application } from 'pixi.js';\nimport type { GameConfig } from './config';\nimport { EventBus, GameEvents } from './events';\nimport { Module } from './module';\nimport type { PlatformAdapter } from './platform';\nimport { detectPlatformName } from './platform';\nimport { WebAdapter } from './platform-web-adapter';\nimport { ScreenAdapter } from './screen';\nimport type { DisplayObjectFactory } from './factory';\nimport { DefaultDisplayObjectFactory } from './factory';\n\n/**\n * Framework main entry point.\n * Initializes the PixiJS renderer and coordinates all modules.\n */\nexport class GameApplication {\n /** PixiJS Application instance */\n readonly pixiApp: Application;\n\n /** Event bus for module communication */\n readonly events = new EventBus();\n\n /** Display object factory (Constitution VI) */\n readonly factory: DisplayObjectFactory;\n\n /** Registered modules */\n private modules = new Map<string, Module>();\n\n /** Platform adapter */\n private _platform!: PlatformAdapter;\n\n /** Screen adapter */\n private _screen!: ScreenAdapter;\n\n /** Framework config */\n private _config: GameConfig = {};\n\n /** Whether in development mode */\n isDev = false;\n\n /** Get framework configuration (read-only) */\n get config(): Readonly<GameConfig> {\n return this._config;\n }\n\n /** Application state */\n private state: 'idle' | 'initializing' | 'running' | 'destroying' | 'destroyed' = 'idle';\n\n constructor(factory?: DisplayObjectFactory) {\n this.pixiApp = new Application();\n this.factory = factory ?? new DefaultDisplayObjectFactory();\n }\n\n /**\n * Initialize the framework with configuration.\n * Creates PixiJS Application, selects platform adapter, and enables modules.\n */\n async init(config: GameConfig = {}): Promise<this> {\n if (this.state !== 'idle') {\n throw new Error(`[GameApplication] Cannot init in state \"${this.state}\"`);\n }\n\n this.state = 'initializing';\n this._config = config;\n this.isDev = config.debug ?? false;\n\n // Setup platform adapter first to access system info\n await this.setupPlatform(config.platform ?? 'auto');\n\n // Get screen info from platform adapter (cross-platform compatible)\n const sysInfo = this._platform.getSystemInfo();\n\n // Initialize PixiJS v8 Application (async)\n await this.pixiApp.init({\n width: config.width ?? sysInfo.screenWidth,\n height: config.height ?? sysInfo.screenHeight,\n backgroundColor: config.backgroundColor ?? 0x000000,\n resolution: config.resolution ?? sysInfo.pixelRatio,\n antialias: config.antialias ?? true,\n autoDensity: true,\n preference: 'webgl',\n });\n\n // Setup screen adapter (event-driven resize via PlatformAdapter.onResize)\n this._screen = new ScreenAdapter(this.pixiApp, this._platform, this.events);\n this._screen.start();\n\n // Register WebGL context loss handlers\n this.setupContextLossHandling();\n\n // Enable all registered modules\n await this.enableModules();\n\n this.state = 'running';\n this.events.emit(GameEvents.APP_INIT);\n return this;\n }\n\n /**\n * Register a module with the framework.\n */\n registerModule(module: Module): this {\n if (this.modules.has(module.name)) {\n throw new Error(`[GameApplication] Module \"${module.name}\" is already registered`);\n }\n module.onRegister(this);\n this.modules.set(module.name, module);\n return this;\n }\n\n /**\n * Get a registered module by name.\n */\n getModule<T extends Module>(name: string): T | undefined {\n return this.modules.get(name) as T | undefined;\n }\n\n /**\n * Get the platform adapter.\n */\n get platform(): PlatformAdapter {\n return this._platform;\n }\n\n /**\n * Get the screen adapter.\n */\n get screen(): ScreenAdapter {\n return this._screen;\n }\n\n /**\n * Destroy the framework and release all resources.\n * Order: scenes → modules → assets → renderer\n */\n destroy(): void {\n if (this.state === 'destroyed' || this.state === 'destroying') return;\n\n this.state = 'destroying';\n\n // Destroy modules in reverse order\n const moduleNames = [...this.modules.keys()].reverse();\n for (const name of moduleNames) {\n const mod = this.modules.get(name)!;\n mod.onDisable();\n mod.onDestroy();\n }\n this.modules.clear();\n\n // Stop screen adapter\n this._screen?.stop();\n\n // Destroy PixiJS application\n this.pixiApp.destroy(true);\n this.events.clear();\n\n this.state = 'destroyed';\n }\n\n /**\n * Setup platform adapter based on config or auto-detection.\n * For mini-game platforms (WeChat/Douyin), user must provide adapter instance\n * since dynamic imports are not supported in mini-game environments.\n */\n private setupPlatform(platformName: string): void {\n // Use provided adapter if available\n if (this._config.platformAdapter) {\n this._platform = this._config.platformAdapter;\n return;\n }\n\n const detected = platformName === 'auto' ? detectPlatformName() : platformName;\n\n switch (detected) {\n case 'wechat':\n case 'douyin':\n throw new Error(\n `[GameApplication] Platform \"${detected}\" requires explicit adapter. ` +\n `Please import and pass it via config.platformAdapter. ` +\n `Example: import { ${detected === 'wechat' ? 'WechatAdapter' : 'DouyinAdapter'} } from ` +\n `'@ksgames26/platform-${detected}'; init({ platformAdapter: new ${detected === 'wechat' ? 'WechatAdapter' : 'DouyinAdapter'}() })`\n );\n case 'web':\n default:\n this._platform = new WebAdapter();\n break;\n }\n }\n\n /**\n * Register WebGL context loss handling with auto-recovery.\n * PixiJS v8 handles the actual recovery; we emit events for business logic.\n */\n private setupContextLossHandling(): void {\n const renderer = this.pixiApp.renderer as unknown as {\n on(event: string, handler: () => void): void;\n };\n\n renderer.on('contextlost', () => {\n this.events.emit(GameEvents.APP_CONTEXT_LOST);\n });\n\n renderer.on('contextrestored', () => {\n this.events.emit(GameEvents.APP_CONTEXT_RESTORED);\n });\n }\n\n /**\n * Enable all registered modules.\n */\n private async enableModules(): Promise<void> {\n for (const mod of this.modules.values()) {\n await mod.onEnable();\n }\n }\n}\n"],"names":["GameApplication","factory","__publicField","EventBus","Application","DefaultDisplayObjectFactory","config","sysInfo","ScreenAdapter","GameEvents","module","name","moduleNames","mod","_a","platformName","detected","detectPlatformName","WebAdapter","renderer"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ "use strict";var t=Object.defineProperty;var o=(l,e,s)=>e in l?t(l,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):l[e]=s;var a=(l,e,s)=>o(l,typeof e!="symbol"?e+"":e,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class n{constructor(){a(this,"app");a(this,"enabled",!1)}onRegister(e){this.app=e}onEnable(){return this.enabled=!0,Promise.resolve()}onDisable(){this.enabled=!1}onDestroy(){this.enabled=!1}}exports.Module=n;
2
+ //# sourceMappingURL=index3.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index3.cjs","sources":["../src/module.ts"],"sourcesContent":["import type { GameApplication } from './application';\n\n/**\n * Abstract base class for framework modules.\n * Each module is an independent npm package, loaded via tree-shaking.\n */\nexport abstract class Module {\n /** Module unique identifier */\n abstract readonly name: string;\n\n /** Module version */\n abstract readonly version: string;\n\n /** Framework instance reference (injected on register) */\n protected app!: GameApplication;\n\n /** Whether the module is enabled */\n enabled = false;\n\n /**\n * Called when the module is registered with the framework.\n * Receives the GameApplication instance for dependency injection.\n */\n onRegister(_app: GameApplication): void {\n this.app = _app;\n }\n\n /**\n * Enable the module. Can be async to support resource loading.\n */\n onEnable(): Promise<void> {\n this.enabled = true;\n return Promise.resolve();\n }\n\n /**\n * Disable the module.\n */\n onDisable(): void {\n this.enabled = false;\n }\n\n /**\n * Destroy the module and release all resources.\n */\n onDestroy(): void {\n this.enabled = false;\n }\n}\n"],"names":["Module","__publicField","_app"],"mappings":"oPAMO,MAAeA,CAAO,CAAtB,cAQKC,EAAA,YAGVA,EAAA,eAAU,IAMV,WAAWC,EAA6B,CACtC,KAAK,IAAMA,CACb,CAKA,UAA0B,CACxB,YAAK,QAAU,GACR,QAAQ,QAAA,CACjB,CAKA,WAAkB,CAChB,KAAK,QAAU,EACjB,CAKA,WAAkB,CAChB,KAAK,QAAU,EACjB,CACF"}
package/dist/index3.js ADDED
@@ -0,0 +1,40 @@
1
+ var n = Object.defineProperty;
2
+ var o = (s, e, a) => e in s ? n(s, e, { enumerable: !0, configurable: !0, writable: !0, value: a }) : s[e] = a;
3
+ var l = (s, e, a) => o(s, typeof e != "symbol" ? e + "" : e, a);
4
+ class r {
5
+ constructor() {
6
+ /** Framework instance reference (injected on register) */
7
+ l(this, "app");
8
+ /** Whether the module is enabled */
9
+ l(this, "enabled", !1);
10
+ }
11
+ /**
12
+ * Called when the module is registered with the framework.
13
+ * Receives the GameApplication instance for dependency injection.
14
+ */
15
+ onRegister(e) {
16
+ this.app = e;
17
+ }
18
+ /**
19
+ * Enable the module. Can be async to support resource loading.
20
+ */
21
+ onEnable() {
22
+ return this.enabled = !0, Promise.resolve();
23
+ }
24
+ /**
25
+ * Disable the module.
26
+ */
27
+ onDisable() {
28
+ this.enabled = !1;
29
+ }
30
+ /**
31
+ * Destroy the module and release all resources.
32
+ */
33
+ onDestroy() {
34
+ this.enabled = !1;
35
+ }
36
+ }
37
+ export {
38
+ r as Module
39
+ };
40
+ //# sourceMappingURL=index3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index3.js","sources":["../src/module.ts"],"sourcesContent":["import type { GameApplication } from './application';\n\n/**\n * Abstract base class for framework modules.\n * Each module is an independent npm package, loaded via tree-shaking.\n */\nexport abstract class Module {\n /** Module unique identifier */\n abstract readonly name: string;\n\n /** Module version */\n abstract readonly version: string;\n\n /** Framework instance reference (injected on register) */\n protected app!: GameApplication;\n\n /** Whether the module is enabled */\n enabled = false;\n\n /**\n * Called when the module is registered with the framework.\n * Receives the GameApplication instance for dependency injection.\n */\n onRegister(_app: GameApplication): void {\n this.app = _app;\n }\n\n /**\n * Enable the module. Can be async to support resource loading.\n */\n onEnable(): Promise<void> {\n this.enabled = true;\n return Promise.resolve();\n }\n\n /**\n * Disable the module.\n */\n onDisable(): void {\n this.enabled = false;\n }\n\n /**\n * Destroy the module and release all resources.\n */\n onDestroy(): void {\n this.enabled = false;\n }\n}\n"],"names":["Module","__publicField","_app"],"mappings":";;;AAMO,MAAeA,EAAO;AAAA,EAAtB;AAQK;AAAA,IAAAC,EAAA;AAGV;AAAA,IAAAA,EAAA,iBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMV,WAAWC,GAA6B;AACtC,SAAK,MAAMA;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,WAA0B;AACxB,gBAAK,UAAU,IACR,QAAQ,QAAA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkB;AAChB,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAkB;AAChB,SAAK,UAAU;AAAA,EACjB;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function e(){return typeof wx<"u"&&typeof wx.createCanvas=="function"?"wechat":typeof tt<"u"&&typeof tt.createCanvas=="function"?"douyin":"web"}exports.detectPlatformName=e;
2
+ //# sourceMappingURL=index4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index4.cjs","sources":["../src/platform.ts"],"sourcesContent":["/**\n * Platform adapter interface.\n * Abstracts platform differences for canvas, storage, network, and input.\n */\nexport interface PlatformAdapter {\n /** Create the main canvas element */\n createCanvas(): HTMLCanvasElement;\n\n /** Create an image element */\n createImage(): HTMLImageElement;\n\n /** Get local storage implementation */\n getStorage(): StorageLike;\n\n /** Register a frame callback */\n requestAnimationFrame(callback: FrameRequestCallback): number;\n\n /** Cancel a frame callback */\n cancelAnimationFrame(id: number): void;\n\n /** HTTP request (fetch-compatible) */\n fetch(url: string, init?: RequestInit): Promise<Response>;\n\n /** Resolve an asset path to platform-specific format */\n resolvePath(path: string): string;\n\n /** Get system information */\n getSystemInfo(): SystemInfo;\n\n /**\n * Register a callback for window/canvas resize events.\n * Uses platform-native resize events (zero polling overhead).\n * @returns Unsubscribe function to remove the callback\n */\n onResize(callback: (width: number, height: number) => void): () => void;\n\n /** Register touch start handler */\n onTouchStart(callback: (event: TouchEvent) => void): void;\n\n /** Register touch move handler */\n onTouchMove(callback: (event: TouchEvent) => void): void;\n\n /** Register touch end handler */\n onTouchEnd(callback: (event: TouchEvent) => void): void;\n}\n\n/**\n * Minimal storage interface compatible with localStorage and mini-game APIs.\n */\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n clear(): void;\n}\n\n/**\n * System information returned by platform adapter.\n */\nexport interface SystemInfo {\n screenWidth: number;\n screenHeight: number;\n pixelRatio: number;\n platform: 'web' | 'wechat' | 'douyin';\n systemVersion: string;\n}\n\n/**\n * Auto-detect current platform and return appropriate adapter name.\n * Detection order: wx → tt → web\n */\nexport function detectPlatformName(): 'wechat' | 'douyin' | 'web' {\n if (typeof wx !== 'undefined' && typeof wx.createCanvas === 'function') {\n return 'wechat';\n }\n if (typeof tt !== 'undefined' && typeof tt.createCanvas === 'function') {\n return 'douyin';\n }\n return 'web';\n}\n\n// Type declarations for mini-game global objects\ndeclare const wx: { createCanvas?: () => HTMLCanvasElement } | undefined;\ndeclare const tt: { createCanvas?: () => HTMLCanvasElement } | undefined;\n"],"names":["detectPlatformName"],"mappings":"gFAuEO,SAASA,GAAkD,CAChE,OAAI,OAAO,GAAO,KAAe,OAAO,GAAG,cAAiB,WACnD,SAEL,OAAO,GAAO,KAAe,OAAO,GAAG,cAAiB,WACnD,SAEF,KACT"}
package/dist/index4.js ADDED
@@ -0,0 +1,7 @@
1
+ function e() {
2
+ return typeof wx < "u" && typeof wx.createCanvas == "function" ? "wechat" : typeof tt < "u" && typeof tt.createCanvas == "function" ? "douyin" : "web";
3
+ }
4
+ export {
5
+ e as detectPlatformName
6
+ };
7
+ //# sourceMappingURL=index4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index4.js","sources":["../src/platform.ts"],"sourcesContent":["/**\n * Platform adapter interface.\n * Abstracts platform differences for canvas, storage, network, and input.\n */\nexport interface PlatformAdapter {\n /** Create the main canvas element */\n createCanvas(): HTMLCanvasElement;\n\n /** Create an image element */\n createImage(): HTMLImageElement;\n\n /** Get local storage implementation */\n getStorage(): StorageLike;\n\n /** Register a frame callback */\n requestAnimationFrame(callback: FrameRequestCallback): number;\n\n /** Cancel a frame callback */\n cancelAnimationFrame(id: number): void;\n\n /** HTTP request (fetch-compatible) */\n fetch(url: string, init?: RequestInit): Promise<Response>;\n\n /** Resolve an asset path to platform-specific format */\n resolvePath(path: string): string;\n\n /** Get system information */\n getSystemInfo(): SystemInfo;\n\n /**\n * Register a callback for window/canvas resize events.\n * Uses platform-native resize events (zero polling overhead).\n * @returns Unsubscribe function to remove the callback\n */\n onResize(callback: (width: number, height: number) => void): () => void;\n\n /** Register touch start handler */\n onTouchStart(callback: (event: TouchEvent) => void): void;\n\n /** Register touch move handler */\n onTouchMove(callback: (event: TouchEvent) => void): void;\n\n /** Register touch end handler */\n onTouchEnd(callback: (event: TouchEvent) => void): void;\n}\n\n/**\n * Minimal storage interface compatible with localStorage and mini-game APIs.\n */\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n clear(): void;\n}\n\n/**\n * System information returned by platform adapter.\n */\nexport interface SystemInfo {\n screenWidth: number;\n screenHeight: number;\n pixelRatio: number;\n platform: 'web' | 'wechat' | 'douyin';\n systemVersion: string;\n}\n\n/**\n * Auto-detect current platform and return appropriate adapter name.\n * Detection order: wx → tt → web\n */\nexport function detectPlatformName(): 'wechat' | 'douyin' | 'web' {\n if (typeof wx !== 'undefined' && typeof wx.createCanvas === 'function') {\n return 'wechat';\n }\n if (typeof tt !== 'undefined' && typeof tt.createCanvas === 'function') {\n return 'douyin';\n }\n return 'web';\n}\n\n// Type declarations for mini-game global objects\ndeclare const wx: { createCanvas?: () => HTMLCanvasElement } | undefined;\ndeclare const tt: { createCanvas?: () => HTMLCanvasElement } | undefined;\n"],"names":["detectPlatformName"],"mappings":"AAuEO,SAASA,IAAkD;AAChE,SAAI,OAAO,KAAO,OAAe,OAAO,GAAG,gBAAiB,aACnD,WAEL,OAAO,KAAO,OAAe,OAAO,GAAG,gBAAiB,aACnD,WAEF;AACT;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class r{getItem(e){return localStorage.getItem(e)}setItem(e,t){localStorage.setItem(e,t)}removeItem(e){localStorage.removeItem(e)}clear(){localStorage.clear()}}class o{createCanvas(){return document.createElement("canvas")}createImage(){return new Image}getStorage(){return new r}requestAnimationFrame(e){return window.requestAnimationFrame(e)}cancelAnimationFrame(e){window.cancelAnimationFrame(e)}async fetch(e,t){return globalThis.fetch(e,t)}resolvePath(e){return e}getSystemInfo(){return{screenWidth:window.innerWidth,screenHeight:window.innerHeight,pixelRatio:window.devicePixelRatio??1,platform:"web",systemVersion:navigator.userAgent}}onResize(e){const t=()=>{e(window.innerWidth,window.innerHeight)};return window.addEventListener("resize",t),()=>{window.removeEventListener("resize",t)}}onTouchStart(e){window.addEventListener("touchstart",e)}onTouchMove(e){window.addEventListener("touchmove",e)}onTouchEnd(e){window.addEventListener("touchend",e)}}exports.WebAdapter=o;
2
+ //# sourceMappingURL=index5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index5.cjs","sources":["../src/platform-web-adapter.ts"],"sourcesContent":["import type { PlatformAdapter, StorageLike, SystemInfo } from './platform';\n\n/**\n * Web Storage implementation using localStorage.\n */\nclass WebStorage implements StorageLike {\n getItem(key: string): string | null {\n return localStorage.getItem(key);\n }\n\n setItem(key: string, value: string): void {\n localStorage.setItem(key, value);\n }\n\n removeItem(key: string): void {\n localStorage.removeItem(key);\n }\n\n clear(): void {\n localStorage.clear();\n }\n}\n\n/**\n * Web platform adapter.\n * Uses standard browser APIs.\n * Included in core package to avoid dynamic imports (mini-game compatibility).\n */\nexport class WebAdapter implements PlatformAdapter {\n createCanvas(): HTMLCanvasElement {\n return document.createElement('canvas');\n }\n\n createImage(): HTMLImageElement {\n return new Image();\n }\n\n getStorage(): StorageLike {\n return new WebStorage();\n }\n\n requestAnimationFrame(callback: FrameRequestCallback): number {\n return window.requestAnimationFrame(callback);\n }\n\n cancelAnimationFrame(id: number): void {\n window.cancelAnimationFrame(id);\n }\n\n async fetch(url: string, init?: RequestInit): Promise<Response> {\n return globalThis.fetch(url, init);\n }\n\n resolvePath(path: string): string {\n return path;\n }\n\n getSystemInfo(): SystemInfo {\n return {\n screenWidth: window.innerWidth,\n screenHeight: window.innerHeight,\n pixelRatio: window.devicePixelRatio ?? 1,\n platform: 'web',\n systemVersion: navigator.userAgent,\n };\n }\n\n onResize(callback: (width: number, height: number) => void): () => void {\n const handler = () => {\n callback(window.innerWidth, window.innerHeight);\n };\n window.addEventListener('resize', handler);\n return () => {\n window.removeEventListener('resize', handler);\n };\n }\n\n onTouchStart(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchstart', callback as EventListener);\n }\n\n onTouchMove(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchmove', callback as EventListener);\n }\n\n onTouchEnd(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchend', callback as EventListener);\n }\n}\n"],"names":["WebStorage","key","value","WebAdapter","callback","id","url","init","path","handler"],"mappings":"gFAKA,MAAMA,CAAkC,CACtC,QAAQC,EAA4B,CAClC,OAAO,aAAa,QAAQA,CAAG,CACjC,CAEA,QAAQA,EAAaC,EAAqB,CACxC,aAAa,QAAQD,EAAKC,CAAK,CACjC,CAEA,WAAWD,EAAmB,CAC5B,aAAa,WAAWA,CAAG,CAC7B,CAEA,OAAc,CACZ,aAAa,MAAA,CACf,CACF,CAOO,MAAME,CAAsC,CACjD,cAAkC,CAChC,OAAO,SAAS,cAAc,QAAQ,CACxC,CAEA,aAAgC,CAC9B,OAAO,IAAI,KACb,CAEA,YAA0B,CACxB,OAAO,IAAIH,CACb,CAEA,sBAAsBI,EAAwC,CAC5D,OAAO,OAAO,sBAAsBA,CAAQ,CAC9C,CAEA,qBAAqBC,EAAkB,CACrC,OAAO,qBAAqBA,CAAE,CAChC,CAEA,MAAM,MAAMC,EAAaC,EAAuC,CAC9D,OAAO,WAAW,MAAMD,EAAKC,CAAI,CACnC,CAEA,YAAYC,EAAsB,CAChC,OAAOA,CACT,CAEA,eAA4B,CAC1B,MAAO,CACL,YAAa,OAAO,WACpB,aAAc,OAAO,YACrB,WAAY,OAAO,kBAAoB,EACvC,SAAU,MACV,cAAe,UAAU,SAAA,CAE7B,CAEA,SAASJ,EAA+D,CACtE,MAAMK,EAAU,IAAM,CACpBL,EAAS,OAAO,WAAY,OAAO,WAAW,CAChD,EACA,cAAO,iBAAiB,SAAUK,CAAO,EAClC,IAAM,CACX,OAAO,oBAAoB,SAAUA,CAAO,CAC9C,CACF,CAEA,aAAaL,EAA6C,CACxD,OAAO,iBAAiB,aAAcA,CAAyB,CACjE,CAEA,YAAYA,EAA6C,CACvD,OAAO,iBAAiB,YAAaA,CAAyB,CAChE,CAEA,WAAWA,EAA6C,CACtD,OAAO,iBAAiB,WAAYA,CAAyB,CAC/D,CACF"}
package/dist/index5.js ADDED
@@ -0,0 +1,67 @@
1
+ class r {
2
+ getItem(e) {
3
+ return localStorage.getItem(e);
4
+ }
5
+ setItem(e, t) {
6
+ localStorage.setItem(e, t);
7
+ }
8
+ removeItem(e) {
9
+ localStorage.removeItem(e);
10
+ }
11
+ clear() {
12
+ localStorage.clear();
13
+ }
14
+ }
15
+ class o {
16
+ createCanvas() {
17
+ return document.createElement("canvas");
18
+ }
19
+ createImage() {
20
+ return new Image();
21
+ }
22
+ getStorage() {
23
+ return new r();
24
+ }
25
+ requestAnimationFrame(e) {
26
+ return window.requestAnimationFrame(e);
27
+ }
28
+ cancelAnimationFrame(e) {
29
+ window.cancelAnimationFrame(e);
30
+ }
31
+ async fetch(e, t) {
32
+ return globalThis.fetch(e, t);
33
+ }
34
+ resolvePath(e) {
35
+ return e;
36
+ }
37
+ getSystemInfo() {
38
+ return {
39
+ screenWidth: window.innerWidth,
40
+ screenHeight: window.innerHeight,
41
+ pixelRatio: window.devicePixelRatio ?? 1,
42
+ platform: "web",
43
+ systemVersion: navigator.userAgent
44
+ };
45
+ }
46
+ onResize(e) {
47
+ const t = () => {
48
+ e(window.innerWidth, window.innerHeight);
49
+ };
50
+ return window.addEventListener("resize", t), () => {
51
+ window.removeEventListener("resize", t);
52
+ };
53
+ }
54
+ onTouchStart(e) {
55
+ window.addEventListener("touchstart", e);
56
+ }
57
+ onTouchMove(e) {
58
+ window.addEventListener("touchmove", e);
59
+ }
60
+ onTouchEnd(e) {
61
+ window.addEventListener("touchend", e);
62
+ }
63
+ }
64
+ export {
65
+ o as WebAdapter
66
+ };
67
+ //# sourceMappingURL=index5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index5.js","sources":["../src/platform-web-adapter.ts"],"sourcesContent":["import type { PlatformAdapter, StorageLike, SystemInfo } from './platform';\n\n/**\n * Web Storage implementation using localStorage.\n */\nclass WebStorage implements StorageLike {\n getItem(key: string): string | null {\n return localStorage.getItem(key);\n }\n\n setItem(key: string, value: string): void {\n localStorage.setItem(key, value);\n }\n\n removeItem(key: string): void {\n localStorage.removeItem(key);\n }\n\n clear(): void {\n localStorage.clear();\n }\n}\n\n/**\n * Web platform adapter.\n * Uses standard browser APIs.\n * Included in core package to avoid dynamic imports (mini-game compatibility).\n */\nexport class WebAdapter implements PlatformAdapter {\n createCanvas(): HTMLCanvasElement {\n return document.createElement('canvas');\n }\n\n createImage(): HTMLImageElement {\n return new Image();\n }\n\n getStorage(): StorageLike {\n return new WebStorage();\n }\n\n requestAnimationFrame(callback: FrameRequestCallback): number {\n return window.requestAnimationFrame(callback);\n }\n\n cancelAnimationFrame(id: number): void {\n window.cancelAnimationFrame(id);\n }\n\n async fetch(url: string, init?: RequestInit): Promise<Response> {\n return globalThis.fetch(url, init);\n }\n\n resolvePath(path: string): string {\n return path;\n }\n\n getSystemInfo(): SystemInfo {\n return {\n screenWidth: window.innerWidth,\n screenHeight: window.innerHeight,\n pixelRatio: window.devicePixelRatio ?? 1,\n platform: 'web',\n systemVersion: navigator.userAgent,\n };\n }\n\n onResize(callback: (width: number, height: number) => void): () => void {\n const handler = () => {\n callback(window.innerWidth, window.innerHeight);\n };\n window.addEventListener('resize', handler);\n return () => {\n window.removeEventListener('resize', handler);\n };\n }\n\n onTouchStart(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchstart', callback as EventListener);\n }\n\n onTouchMove(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchmove', callback as EventListener);\n }\n\n onTouchEnd(callback: (event: TouchEvent) => void): void {\n window.addEventListener('touchend', callback as EventListener);\n }\n}\n"],"names":["WebStorage","key","value","WebAdapter","callback","id","url","init","path","handler"],"mappings":"AAKA,MAAMA,EAAkC;AAAA,EACtC,QAAQC,GAA4B;AAClC,WAAO,aAAa,QAAQA,CAAG;AAAA,EACjC;AAAA,EAEA,QAAQA,GAAaC,GAAqB;AACxC,iBAAa,QAAQD,GAAKC,CAAK;AAAA,EACjC;AAAA,EAEA,WAAWD,GAAmB;AAC5B,iBAAa,WAAWA,CAAG;AAAA,EAC7B;AAAA,EAEA,QAAc;AACZ,iBAAa,MAAA;AAAA,EACf;AACF;AAOO,MAAME,EAAsC;AAAA,EACjD,eAAkC;AAChC,WAAO,SAAS,cAAc,QAAQ;AAAA,EACxC;AAAA,EAEA,cAAgC;AAC9B,WAAO,IAAI,MAAA;AAAA,EACb;AAAA,EAEA,aAA0B;AACxB,WAAO,IAAIH,EAAA;AAAA,EACb;AAAA,EAEA,sBAAsBI,GAAwC;AAC5D,WAAO,OAAO,sBAAsBA,CAAQ;AAAA,EAC9C;AAAA,EAEA,qBAAqBC,GAAkB;AACrC,WAAO,qBAAqBA,CAAE;AAAA,EAChC;AAAA,EAEA,MAAM,MAAMC,GAAaC,GAAuC;AAC9D,WAAO,WAAW,MAAMD,GAAKC,CAAI;AAAA,EACnC;AAAA,EAEA,YAAYC,GAAsB;AAChC,WAAOA;AAAA,EACT;AAAA,EAEA,gBAA4B;AAC1B,WAAO;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,cAAc,OAAO;AAAA,MACrB,YAAY,OAAO,oBAAoB;AAAA,MACvC,UAAU;AAAA,MACV,eAAe,UAAU;AAAA,IAAA;AAAA,EAE7B;AAAA,EAEA,SAASJ,GAA+D;AACtE,UAAMK,IAAU,MAAM;AACpB,MAAAL,EAAS,OAAO,YAAY,OAAO,WAAW;AAAA,IAChD;AACA,kBAAO,iBAAiB,UAAUK,CAAO,GAClC,MAAM;AACX,aAAO,oBAAoB,UAAUA,CAAO;AAAA,IAC9C;AAAA,EACF;AAAA,EAEA,aAAaL,GAA6C;AACxD,WAAO,iBAAiB,cAAcA,CAAyB;AAAA,EACjE;AAAA,EAEA,YAAYA,GAA6C;AACvD,WAAO,iBAAiB,aAAaA,CAAyB;AAAA,EAChE;AAAA,EAEA,WAAWA,GAA6C;AACtD,WAAO,iBAAiB,YAAYA,CAAyB;AAAA,EAC/D;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";var E=Object.defineProperty;var l=(t,e,s)=>e in t?E(t,e,{enumerable:!0,configurable:!0,writable:!0,value:s}):t[e]=s;var n=(t,e,s)=>l(t,typeof e!="symbol"?e+"":e,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class h{constructor(){n(this,"handlers",new Map)}on(e,s){return this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(s),()=>this.off(e,s)}once(e,s){const r=(...a)=>{this.off(e,r),s(...a)};return this.on(e,r)}off(e,s){var r;(r=this.handlers.get(e))==null||r.delete(s)}emit(e,...s){const r=this.handlers.get(e);if(r)for(const a of r)try{a(...s)}catch(o){console.error(`[EventBus] Error in handler for "${e}":`,o)}}clear(e){e?this.handlers.delete(e):this.handlers.clear()}}const d={APP_INIT:"app:init",APP_CONTEXT_LOST:"app:contextlost",APP_CONTEXT_RESTORED:"app:contextrestored",APP_RENDERER_FALLBACK:"app:rendererfallback",SCREEN_RESIZE:"screen:resize",SCENE_SWITCH:"scene:switch",SCENE_SWITCHED:"scene:switched",ASSET_LOADED:"asset:loaded",ASSET_UNLOADED:"asset:unloaded",ASSET_ERROR:"asset:error"};exports.EventBus=h;exports.GameEvents=d;
2
+ //# sourceMappingURL=index6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index6.cjs","sources":["../src/events.ts"],"sourcesContent":["type EventHandler = (...args: unknown[]) => void;\n\n/**\n * Typed event bus for framework communication.\n * Modules MUST communicate through events, never by direct state access.\n */\nexport class EventBus {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event.\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event once. Auto-removes after first invocation.\n */\n once(event: string, handler: EventHandler): () => void {\n const wrapper: EventHandler = (...args) => {\n this.off(event, wrapper);\n handler(...args);\n };\n return this.on(event, wrapper);\n }\n\n /**\n * Unsubscribe from an event.\n */\n off(event: string, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event to all subscribers.\n */\n emit(event: string, ...args: unknown[]): void {\n const handlers = this.handlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(...args);\n } catch (error) {\n console.error(`[EventBus] Error in handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event, or all events.\n */\n clear(event?: string): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n}\n\n/**\n * Framework event name constants.\n */\nexport const GameEvents = {\n APP_INIT: 'app:init',\n APP_CONTEXT_LOST: 'app:contextlost',\n APP_CONTEXT_RESTORED: 'app:contextrestored',\n APP_RENDERER_FALLBACK: 'app:rendererfallback',\n SCREEN_RESIZE: 'screen:resize',\n SCENE_SWITCH: 'scene:switch',\n SCENE_SWITCHED: 'scene:switched',\n ASSET_LOADED: 'asset:loaded',\n ASSET_UNLOADED: 'asset:unloaded',\n ASSET_ERROR: 'asset:error',\n} as const;\n\nexport type GameEventName = (typeof GameEvents)[keyof typeof GameEvents];\n"],"names":["EventBus","__publicField","event","handler","wrapper","args","_a","handlers","error","GameEvents"],"mappings":"oPAMO,MAAMA,CAAS,CAAf,cACGC,EAAA,oBAAe,KAMvB,GAAGC,EAAeC,EAAmC,CACnD,OAAK,KAAK,SAAS,IAAID,CAAK,GAC1B,KAAK,SAAS,IAAIA,EAAO,IAAI,GAAK,EAEpC,KAAK,SAAS,IAAIA,CAAK,EAAG,IAAIC,CAAO,EAC9B,IAAM,KAAK,IAAID,EAAOC,CAAO,CACtC,CAKA,KAAKD,EAAeC,EAAmC,CACrD,MAAMC,EAAwB,IAAIC,IAAS,CACzC,KAAK,IAAIH,EAAOE,CAAO,EACvBD,EAAQ,GAAGE,CAAI,CACjB,EACA,OAAO,KAAK,GAAGH,EAAOE,CAAO,CAC/B,CAKA,IAAIF,EAAeC,EAA6B,QAC9CG,EAAA,KAAK,SAAS,IAAIJ,CAAK,IAAvB,MAAAI,EAA0B,OAAOH,EACnC,CAKA,KAAKD,KAAkBG,EAAuB,CAC5C,MAAME,EAAW,KAAK,SAAS,IAAIL,CAAK,EACxC,GAAIK,EACF,UAAWJ,KAAWI,EACpB,GAAI,CACFJ,EAAQ,GAAGE,CAAI,CACjB,OAASG,EAAO,CACd,QAAQ,MAAM,oCAAoCN,CAAK,KAAMM,CAAK,CACpE,CAGN,CAKA,MAAMN,EAAsB,CACtBA,EACF,KAAK,SAAS,OAAOA,CAAK,EAE1B,KAAK,SAAS,MAAA,CAElB,CACF,CAKO,MAAMO,EAAa,CACxB,SAAU,WACV,iBAAkB,kBAClB,qBAAsB,sBACtB,sBAAuB,uBACvB,cAAe,gBACf,aAAc,eACd,eAAgB,iBAChB,aAAc,eACd,eAAgB,iBAChB,YAAa,aACf"}
package/dist/index6.js ADDED
@@ -0,0 +1,67 @@
1
+ var E = Object.defineProperty;
2
+ var h = (t, e, s) => e in t ? E(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
3
+ var n = (t, e, s) => h(t, typeof e != "symbol" ? e + "" : e, s);
4
+ class d {
5
+ constructor() {
6
+ n(this, "handlers", /* @__PURE__ */ new Map());
7
+ }
8
+ /**
9
+ * Subscribe to an event.
10
+ * @returns Unsubscribe function
11
+ */
12
+ on(e, s) {
13
+ return this.handlers.has(e) || this.handlers.set(e, /* @__PURE__ */ new Set()), this.handlers.get(e).add(s), () => this.off(e, s);
14
+ }
15
+ /**
16
+ * Subscribe to an event once. Auto-removes after first invocation.
17
+ */
18
+ once(e, s) {
19
+ const r = (...a) => {
20
+ this.off(e, r), s(...a);
21
+ };
22
+ return this.on(e, r);
23
+ }
24
+ /**
25
+ * Unsubscribe from an event.
26
+ */
27
+ off(e, s) {
28
+ var r;
29
+ (r = this.handlers.get(e)) == null || r.delete(s);
30
+ }
31
+ /**
32
+ * Emit an event to all subscribers.
33
+ */
34
+ emit(e, ...s) {
35
+ const r = this.handlers.get(e);
36
+ if (r)
37
+ for (const a of r)
38
+ try {
39
+ a(...s);
40
+ } catch (o) {
41
+ console.error(`[EventBus] Error in handler for "${e}":`, o);
42
+ }
43
+ }
44
+ /**
45
+ * Remove all handlers for a specific event, or all events.
46
+ */
47
+ clear(e) {
48
+ e ? this.handlers.delete(e) : this.handlers.clear();
49
+ }
50
+ }
51
+ const i = {
52
+ APP_INIT: "app:init",
53
+ APP_CONTEXT_LOST: "app:contextlost",
54
+ APP_CONTEXT_RESTORED: "app:contextrestored",
55
+ APP_RENDERER_FALLBACK: "app:rendererfallback",
56
+ SCREEN_RESIZE: "screen:resize",
57
+ SCENE_SWITCH: "scene:switch",
58
+ SCENE_SWITCHED: "scene:switched",
59
+ ASSET_LOADED: "asset:loaded",
60
+ ASSET_UNLOADED: "asset:unloaded",
61
+ ASSET_ERROR: "asset:error"
62
+ };
63
+ export {
64
+ d as EventBus,
65
+ i as GameEvents
66
+ };
67
+ //# sourceMappingURL=index6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index6.js","sources":["../src/events.ts"],"sourcesContent":["type EventHandler = (...args: unknown[]) => void;\n\n/**\n * Typed event bus for framework communication.\n * Modules MUST communicate through events, never by direct state access.\n */\nexport class EventBus {\n private handlers = new Map<string, Set<EventHandler>>();\n\n /**\n * Subscribe to an event.\n * @returns Unsubscribe function\n */\n on(event: string, handler: EventHandler): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler);\n return () => this.off(event, handler);\n }\n\n /**\n * Subscribe to an event once. Auto-removes after first invocation.\n */\n once(event: string, handler: EventHandler): () => void {\n const wrapper: EventHandler = (...args) => {\n this.off(event, wrapper);\n handler(...args);\n };\n return this.on(event, wrapper);\n }\n\n /**\n * Unsubscribe from an event.\n */\n off(event: string, handler: EventHandler): void {\n this.handlers.get(event)?.delete(handler);\n }\n\n /**\n * Emit an event to all subscribers.\n */\n emit(event: string, ...args: unknown[]): void {\n const handlers = this.handlers.get(event);\n if (handlers) {\n for (const handler of handlers) {\n try {\n handler(...args);\n } catch (error) {\n console.error(`[EventBus] Error in handler for \"${event}\":`, error);\n }\n }\n }\n }\n\n /**\n * Remove all handlers for a specific event, or all events.\n */\n clear(event?: string): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n}\n\n/**\n * Framework event name constants.\n */\nexport const GameEvents = {\n APP_INIT: 'app:init',\n APP_CONTEXT_LOST: 'app:contextlost',\n APP_CONTEXT_RESTORED: 'app:contextrestored',\n APP_RENDERER_FALLBACK: 'app:rendererfallback',\n SCREEN_RESIZE: 'screen:resize',\n SCENE_SWITCH: 'scene:switch',\n SCENE_SWITCHED: 'scene:switched',\n ASSET_LOADED: 'asset:loaded',\n ASSET_UNLOADED: 'asset:unloaded',\n ASSET_ERROR: 'asset:error',\n} as const;\n\nexport type GameEventName = (typeof GameEvents)[keyof typeof GameEvents];\n"],"names":["EventBus","__publicField","event","handler","wrapper","args","_a","handlers","error","GameEvents"],"mappings":";;;AAMO,MAAMA,EAAS;AAAA,EAAf;AACG,IAAAC,EAAA,sCAAe,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMvB,GAAGC,GAAeC,GAAmC;AACnD,WAAK,KAAK,SAAS,IAAID,CAAK,KAC1B,KAAK,SAAS,IAAIA,GAAO,oBAAI,KAAK,GAEpC,KAAK,SAAS,IAAIA,CAAK,EAAG,IAAIC,CAAO,GAC9B,MAAM,KAAK,IAAID,GAAOC,CAAO;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAKD,GAAeC,GAAmC;AACrD,UAAMC,IAAwB,IAAIC,MAAS;AACzC,WAAK,IAAIH,GAAOE,CAAO,GACvBD,EAAQ,GAAGE,CAAI;AAAA,IACjB;AACA,WAAO,KAAK,GAAGH,GAAOE,CAAO;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAIF,GAAeC,GAA6B;AA7B3C,QAAAG;AA8BH,KAAAA,IAAA,KAAK,SAAS,IAAIJ,CAAK,MAAvB,QAAAI,EAA0B,OAAOH;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,KAAKD,MAAkBG,GAAuB;AAC5C,UAAME,IAAW,KAAK,SAAS,IAAIL,CAAK;AACxC,QAAIK;AACF,iBAAWJ,KAAWI;AACpB,YAAI;AACF,UAAAJ,EAAQ,GAAGE,CAAI;AAAA,QACjB,SAASG,GAAO;AACd,kBAAQ,MAAM,oCAAoCN,CAAK,MAAMM,CAAK;AAAA,QACpE;AAAA,EAGN;AAAA;AAAA;AAAA;AAAA,EAKA,MAAMN,GAAsB;AAC1B,IAAIA,IACF,KAAK,SAAS,OAAOA,CAAK,IAE1B,KAAK,SAAS,MAAA;AAAA,EAElB;AACF;AAKO,MAAMO,IAAa;AAAA,EACxB,UAAU;AAAA,EACV,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,uBAAuB;AAAA,EACvB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,aAAa;AACf;"}
@@ -0,0 +1,2 @@
1
+ "use strict";var n=Object.defineProperty;var h=(i,t,e)=>t in i?n(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var s=(i,t,e)=>h(i,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index6.cjs");class l{constructor(t,e,r){s(this,"app");s(this,"platform");s(this,"events");s(this,"unsubscribe",null);s(this,"lastWidth",0);s(this,"lastHeight",0);this.app=t,this.platform=e,this.events=r}start(){const t=this.platform.getSystemInfo();this.lastWidth=t.screenWidth,this.lastHeight=t.screenHeight,this.unsubscribe=this.platform.onResize((e,r)=>{this.handleResize(e,r)})}stop(){this.unsubscribe&&(this.unsubscribe(),this.unsubscribe=null)}handleResize(t,e){(t!==this.lastWidth||e!==this.lastHeight)&&(this.lastWidth=t,this.lastHeight=e,this.app.renderer.resize(t,e),this.events.emit(a.GameEvents.SCREEN_RESIZE,t,e))}get dimensions(){return{width:this.app.renderer.width,height:this.app.renderer.height}}}exports.ScreenAdapter=l;
2
+ //# sourceMappingURL=index7.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index7.cjs","sources":["../src/screen.ts"],"sourcesContent":["import type { Application } from 'pixi.js';\nimport type { PlatformAdapter } from './platform';\nimport type { EventBus } from './events';\nimport { GameEvents } from './events';\n\n/**\n * Responsive screen adapter.\n * Uses PlatformAdapter.onResize() for event-driven resize detection (zero polling).\n * Emits 'screen:resize' via EventBus when canvas dimensions change.\n */\nexport class ScreenAdapter {\n private app: Application;\n private platform: PlatformAdapter;\n private events: EventBus;\n private unsubscribe: (() => void) | null = null;\n private lastWidth = 0;\n private lastHeight = 0;\n\n constructor(app: Application, platform: PlatformAdapter, events: EventBus) {\n this.app = app;\n this.platform = platform;\n this.events = events;\n }\n\n /**\n * Start listening for resize events via PlatformAdapter.onResize().\n * Event-driven: no ticker polling, zero overhead when idle.\n */\n start(): void {\n // Initialize dimensions from current system info\n const sysInfo = this.platform.getSystemInfo();\n this.lastWidth = sysInfo.screenWidth;\n this.lastHeight = sysInfo.screenHeight;\n\n // Register platform-native resize callback\n this.unsubscribe = this.platform.onResize((width, height) => {\n this.handleResize(width, height);\n });\n }\n\n /**\n * Stop listening for resize events.\n */\n stop(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n }\n\n /**\n * Handle resize: update renderer and emit event.\n */\n private handleResize(width: number, height: number): void {\n if (width !== this.lastWidth || height !== this.lastHeight) {\n this.lastWidth = width;\n this.lastHeight = height;\n this.app.renderer.resize(width, height);\n this.events.emit(GameEvents.SCREEN_RESIZE, width, height);\n }\n }\n\n /**\n * Get current screen dimensions.\n */\n get dimensions(): { width: number; height: number } {\n return {\n width: this.app.renderer.width,\n height: this.app.renderer.height,\n };\n }\n}\n"],"names":["ScreenAdapter","app","platform","events","__publicField","sysInfo","width","height","GameEvents"],"mappings":"oRAUO,MAAMA,CAAc,CAQzB,YAAYC,EAAkBC,EAA2BC,EAAkB,CAPnEC,EAAA,YACAA,EAAA,iBACAA,EAAA,eACAA,EAAA,mBAAmC,MACnCA,EAAA,iBAAY,GACZA,EAAA,kBAAa,GAGnB,KAAK,IAAMH,EACX,KAAK,SAAWC,EAChB,KAAK,OAASC,CAChB,CAMA,OAAc,CAEZ,MAAME,EAAU,KAAK,SAAS,cAAA,EAC9B,KAAK,UAAYA,EAAQ,YACzB,KAAK,WAAaA,EAAQ,aAG1B,KAAK,YAAc,KAAK,SAAS,SAAS,CAACC,EAAOC,IAAW,CAC3D,KAAK,aAAaD,EAAOC,CAAM,CACjC,CAAC,CACH,CAKA,MAAa,CACP,KAAK,cACP,KAAK,YAAA,EACL,KAAK,YAAc,KAEvB,CAKQ,aAAaD,EAAeC,EAAsB,EACpDD,IAAU,KAAK,WAAaC,IAAW,KAAK,cAC9C,KAAK,UAAYD,EACjB,KAAK,WAAaC,EAClB,KAAK,IAAI,SAAS,OAAOD,EAAOC,CAAM,EACtC,KAAK,OAAO,KAAKC,EAAAA,WAAW,cAAeF,EAAOC,CAAM,EAE5D,CAKA,IAAI,YAAgD,CAClD,MAAO,CACL,MAAO,KAAK,IAAI,SAAS,MACzB,OAAQ,KAAK,IAAI,SAAS,MAAA,CAE9B,CACF"}
package/dist/index7.js ADDED
@@ -0,0 +1,50 @@
1
+ var h = Object.defineProperty;
2
+ var n = (i, s, t) => s in i ? h(i, s, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[s] = t;
3
+ var e = (i, s, t) => n(i, typeof s != "symbol" ? s + "" : s, t);
4
+ import { GameEvents as a } from "./index6.js";
5
+ class o {
6
+ constructor(s, t, r) {
7
+ e(this, "app");
8
+ e(this, "platform");
9
+ e(this, "events");
10
+ e(this, "unsubscribe", null);
11
+ e(this, "lastWidth", 0);
12
+ e(this, "lastHeight", 0);
13
+ this.app = s, this.platform = t, this.events = r;
14
+ }
15
+ /**
16
+ * Start listening for resize events via PlatformAdapter.onResize().
17
+ * Event-driven: no ticker polling, zero overhead when idle.
18
+ */
19
+ start() {
20
+ const s = this.platform.getSystemInfo();
21
+ this.lastWidth = s.screenWidth, this.lastHeight = s.screenHeight, this.unsubscribe = this.platform.onResize((t, r) => {
22
+ this.handleResize(t, r);
23
+ });
24
+ }
25
+ /**
26
+ * Stop listening for resize events.
27
+ */
28
+ stop() {
29
+ this.unsubscribe && (this.unsubscribe(), this.unsubscribe = null);
30
+ }
31
+ /**
32
+ * Handle resize: update renderer and emit event.
33
+ */
34
+ handleResize(s, t) {
35
+ (s !== this.lastWidth || t !== this.lastHeight) && (this.lastWidth = s, this.lastHeight = t, this.app.renderer.resize(s, t), this.events.emit(a.SCREEN_RESIZE, s, t));
36
+ }
37
+ /**
38
+ * Get current screen dimensions.
39
+ */
40
+ get dimensions() {
41
+ return {
42
+ width: this.app.renderer.width,
43
+ height: this.app.renderer.height
44
+ };
45
+ }
46
+ }
47
+ export {
48
+ o as ScreenAdapter
49
+ };
50
+ //# sourceMappingURL=index7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index7.js","sources":["../src/screen.ts"],"sourcesContent":["import type { Application } from 'pixi.js';\nimport type { PlatformAdapter } from './platform';\nimport type { EventBus } from './events';\nimport { GameEvents } from './events';\n\n/**\n * Responsive screen adapter.\n * Uses PlatformAdapter.onResize() for event-driven resize detection (zero polling).\n * Emits 'screen:resize' via EventBus when canvas dimensions change.\n */\nexport class ScreenAdapter {\n private app: Application;\n private platform: PlatformAdapter;\n private events: EventBus;\n private unsubscribe: (() => void) | null = null;\n private lastWidth = 0;\n private lastHeight = 0;\n\n constructor(app: Application, platform: PlatformAdapter, events: EventBus) {\n this.app = app;\n this.platform = platform;\n this.events = events;\n }\n\n /**\n * Start listening for resize events via PlatformAdapter.onResize().\n * Event-driven: no ticker polling, zero overhead when idle.\n */\n start(): void {\n // Initialize dimensions from current system info\n const sysInfo = this.platform.getSystemInfo();\n this.lastWidth = sysInfo.screenWidth;\n this.lastHeight = sysInfo.screenHeight;\n\n // Register platform-native resize callback\n this.unsubscribe = this.platform.onResize((width, height) => {\n this.handleResize(width, height);\n });\n }\n\n /**\n * Stop listening for resize events.\n */\n stop(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n }\n\n /**\n * Handle resize: update renderer and emit event.\n */\n private handleResize(width: number, height: number): void {\n if (width !== this.lastWidth || height !== this.lastHeight) {\n this.lastWidth = width;\n this.lastHeight = height;\n this.app.renderer.resize(width, height);\n this.events.emit(GameEvents.SCREEN_RESIZE, width, height);\n }\n }\n\n /**\n * Get current screen dimensions.\n */\n get dimensions(): { width: number; height: number } {\n return {\n width: this.app.renderer.width,\n height: this.app.renderer.height,\n };\n }\n}\n"],"names":["ScreenAdapter","app","platform","events","__publicField","sysInfo","width","height","GameEvents"],"mappings":";;;;AAUO,MAAMA,EAAc;AAAA,EAQzB,YAAYC,GAAkBC,GAA2BC,GAAkB;AAPnE,IAAAC,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,qBAAmC;AACnC,IAAAA,EAAA,mBAAY;AACZ,IAAAA,EAAA,oBAAa;AAGnB,SAAK,MAAMH,GACX,KAAK,WAAWC,GAChB,KAAK,SAASC;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAc;AAEZ,UAAME,IAAU,KAAK,SAAS,cAAA;AAC9B,SAAK,YAAYA,EAAQ,aACzB,KAAK,aAAaA,EAAQ,cAG1B,KAAK,cAAc,KAAK,SAAS,SAAS,CAACC,GAAOC,MAAW;AAC3D,WAAK,aAAaD,GAAOC,CAAM;AAAA,IACjC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAa;AACX,IAAI,KAAK,gBACP,KAAK,YAAA,GACL,KAAK,cAAc;AAAA,EAEvB;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAaD,GAAeC,GAAsB;AACxD,KAAID,MAAU,KAAK,aAAaC,MAAW,KAAK,gBAC9C,KAAK,YAAYD,GACjB,KAAK,aAAaC,GAClB,KAAK,IAAI,SAAS,OAAOD,GAAOC,CAAM,GACtC,KAAK,OAAO,KAAKC,EAAW,eAAeF,GAAOC,CAAM;AAAA,EAE5D;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAgD;AAClD,WAAO;AAAA,MACL,OAAO,KAAK,IAAI,SAAS;AAAA,MACzB,QAAQ,KAAK,IAAI,SAAS;AAAA,IAAA;AAAA,EAE9B;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";var i=Object.defineProperty;var h=(o,t,e)=>t in o?i(o,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[t]=e;var r=(o,t,e)=>h(o,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class a{constructor(t,e,s=0){r(this,"pool",[]);r(this,"factory");r(this,"reset");r(this,"active",0);this.factory=t,this.reset=e,s>0&&this.prewarm(s)}get size(){return this.pool.length}get activeCount(){return this.active}acquire(){return this.active++,this.pool.length>0?this.pool.pop():this.factory()}release(t){this.reset(t),this.pool.push(t),this.active=Math.max(0,this.active-1)}prewarm(t){for(let e=0;e<t;e++)this.pool.push(this.factory())}drain(){this.pool.length=0}}exports.ObjectPool=a;
2
+ //# sourceMappingURL=index8.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index8.cjs","sources":["../src/object-pool.ts"],"sourcesContent":["/**\n * Generic object pool for frequently created/destroyed display objects.\n * Satisfies Constitution I: \"Object Pool MUST be used for frequently\n * created/destroyed display objects (particles, bullets, effects).\"\n *\n * Pure logic - no platform API dependencies.\n */\nexport class ObjectPool<T> {\n private pool: T[] = [];\n private factory: () => T;\n private reset: (obj: T) => void;\n private active = 0;\n\n /**\n * @param factory Function to create a new object\n * @param reset Function to reset an object when returned to pool\n * @param initialSize Number of objects to pre-create\n */\n constructor(factory: () => T, reset: (obj: T) => void, initialSize = 0) {\n this.factory = factory;\n this.reset = reset;\n\n if (initialSize > 0) {\n this.prewarm(initialSize);\n }\n }\n\n /**\n * Number of objects available in the pool.\n */\n get size(): number {\n return this.pool.length;\n }\n\n /**\n * Number of currently active (borrowed) objects.\n */\n get activeCount(): number {\n return this.active;\n }\n\n /**\n * Acquire an object from the pool.\n * Creates a new one if the pool is empty.\n */\n acquire(): T {\n this.active++;\n if (this.pool.length > 0) {\n return this.pool.pop()!;\n }\n return this.factory();\n }\n\n /**\n * Release an object back to the pool.\n * The reset function is called to prepare the object for reuse.\n */\n release(obj: T): void {\n this.reset(obj);\n this.pool.push(obj);\n this.active = Math.max(0, this.active - 1);\n }\n\n /**\n * Pre-warm the pool by creating objects upfront.\n * Useful to avoid allocation spikes at runtime.\n */\n prewarm(count: number): void {\n for (let i = 0; i < count; i++) {\n this.pool.push(this.factory());\n }\n }\n\n /**\n * Drain all objects from the pool.\n */\n drain(): void {\n this.pool.length = 0;\n }\n}\n"],"names":["ObjectPool","factory","reset","initialSize","__publicField","obj","count","i"],"mappings":"oPAOO,MAAMA,CAAc,CAWzB,YAAYC,EAAkBC,EAAyBC,EAAc,EAAG,CAVhEC,EAAA,YAAY,CAAA,GACZA,EAAA,gBACAA,EAAA,cACAA,EAAA,cAAS,GAQf,KAAK,QAAUH,EACf,KAAK,MAAQC,EAETC,EAAc,GAChB,KAAK,QAAQA,CAAW,CAE5B,CAKA,IAAI,MAAe,CACjB,OAAO,KAAK,KAAK,MACnB,CAKA,IAAI,aAAsB,CACxB,OAAO,KAAK,MACd,CAMA,SAAa,CAEX,OADA,KAAK,SACD,KAAK,KAAK,OAAS,EACd,KAAK,KAAK,IAAA,EAEZ,KAAK,QAAA,CACd,CAMA,QAAQE,EAAc,CACpB,KAAK,MAAMA,CAAG,EACd,KAAK,KAAK,KAAKA,CAAG,EAClB,KAAK,OAAS,KAAK,IAAI,EAAG,KAAK,OAAS,CAAC,CAC3C,CAMA,QAAQC,EAAqB,CAC3B,QAASC,EAAI,EAAGA,EAAID,EAAOC,IACzB,KAAK,KAAK,KAAK,KAAK,QAAA,CAAS,CAEjC,CAKA,OAAc,CACZ,KAAK,KAAK,OAAS,CACrB,CACF"}
package/dist/index8.js ADDED
@@ -0,0 +1,61 @@
1
+ var i = Object.defineProperty;
2
+ var h = (r, t, e) => t in r ? i(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
3
+ var s = (r, t, e) => h(r, typeof t != "symbol" ? t + "" : t, e);
4
+ class c {
5
+ /**
6
+ * @param factory Function to create a new object
7
+ * @param reset Function to reset an object when returned to pool
8
+ * @param initialSize Number of objects to pre-create
9
+ */
10
+ constructor(t, e, o = 0) {
11
+ s(this, "pool", []);
12
+ s(this, "factory");
13
+ s(this, "reset");
14
+ s(this, "active", 0);
15
+ this.factory = t, this.reset = e, o > 0 && this.prewarm(o);
16
+ }
17
+ /**
18
+ * Number of objects available in the pool.
19
+ */
20
+ get size() {
21
+ return this.pool.length;
22
+ }
23
+ /**
24
+ * Number of currently active (borrowed) objects.
25
+ */
26
+ get activeCount() {
27
+ return this.active;
28
+ }
29
+ /**
30
+ * Acquire an object from the pool.
31
+ * Creates a new one if the pool is empty.
32
+ */
33
+ acquire() {
34
+ return this.active++, this.pool.length > 0 ? this.pool.pop() : this.factory();
35
+ }
36
+ /**
37
+ * Release an object back to the pool.
38
+ * The reset function is called to prepare the object for reuse.
39
+ */
40
+ release(t) {
41
+ this.reset(t), this.pool.push(t), this.active = Math.max(0, this.active - 1);
42
+ }
43
+ /**
44
+ * Pre-warm the pool by creating objects upfront.
45
+ * Useful to avoid allocation spikes at runtime.
46
+ */
47
+ prewarm(t) {
48
+ for (let e = 0; e < t; e++)
49
+ this.pool.push(this.factory());
50
+ }
51
+ /**
52
+ * Drain all objects from the pool.
53
+ */
54
+ drain() {
55
+ this.pool.length = 0;
56
+ }
57
+ }
58
+ export {
59
+ c as ObjectPool
60
+ };
61
+ //# sourceMappingURL=index8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index8.js","sources":["../src/object-pool.ts"],"sourcesContent":["/**\n * Generic object pool for frequently created/destroyed display objects.\n * Satisfies Constitution I: \"Object Pool MUST be used for frequently\n * created/destroyed display objects (particles, bullets, effects).\"\n *\n * Pure logic - no platform API dependencies.\n */\nexport class ObjectPool<T> {\n private pool: T[] = [];\n private factory: () => T;\n private reset: (obj: T) => void;\n private active = 0;\n\n /**\n * @param factory Function to create a new object\n * @param reset Function to reset an object when returned to pool\n * @param initialSize Number of objects to pre-create\n */\n constructor(factory: () => T, reset: (obj: T) => void, initialSize = 0) {\n this.factory = factory;\n this.reset = reset;\n\n if (initialSize > 0) {\n this.prewarm(initialSize);\n }\n }\n\n /**\n * Number of objects available in the pool.\n */\n get size(): number {\n return this.pool.length;\n }\n\n /**\n * Number of currently active (borrowed) objects.\n */\n get activeCount(): number {\n return this.active;\n }\n\n /**\n * Acquire an object from the pool.\n * Creates a new one if the pool is empty.\n */\n acquire(): T {\n this.active++;\n if (this.pool.length > 0) {\n return this.pool.pop()!;\n }\n return this.factory();\n }\n\n /**\n * Release an object back to the pool.\n * The reset function is called to prepare the object for reuse.\n */\n release(obj: T): void {\n this.reset(obj);\n this.pool.push(obj);\n this.active = Math.max(0, this.active - 1);\n }\n\n /**\n * Pre-warm the pool by creating objects upfront.\n * Useful to avoid allocation spikes at runtime.\n */\n prewarm(count: number): void {\n for (let i = 0; i < count; i++) {\n this.pool.push(this.factory());\n }\n }\n\n /**\n * Drain all objects from the pool.\n */\n drain(): void {\n this.pool.length = 0;\n }\n}\n"],"names":["ObjectPool","factory","reset","initialSize","__publicField","obj","count","i"],"mappings":";;;AAOO,MAAMA,EAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWzB,YAAYC,GAAkBC,GAAyBC,IAAc,GAAG;AAVhE,IAAAC,EAAA,cAAY,CAAA;AACZ,IAAAA,EAAA;AACA,IAAAA,EAAA;AACA,IAAAA,EAAA,gBAAS;AAQf,SAAK,UAAUH,GACf,KAAK,QAAQC,GAETC,IAAc,KAChB,KAAK,QAAQA,CAAW;AAAA,EAE5B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAsB;AACxB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,UAAa;AAEX,WADA,KAAK,UACD,KAAK,KAAK,SAAS,IACd,KAAK,KAAK,IAAA,IAEZ,KAAK,QAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQE,GAAc;AACpB,SAAK,MAAMA,CAAG,GACd,KAAK,KAAK,KAAKA,CAAG,GAClB,KAAK,SAAS,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,QAAQC,GAAqB;AAC3B,aAASC,IAAI,GAAGA,IAAID,GAAOC;AACzB,WAAK,KAAK,KAAK,KAAK,QAAA,CAAS;AAAA,EAEjC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,KAAK,SAAS;AAAA,EACrB;AACF;"}
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("pixi.js");class a{createSprite(e){return new t.Sprite(e)}createContainer(){return new t.Container}createGraphics(){return new t.Graphics}createBitmapText(e,r){return new t.BitmapText({text:r,style:{fontFamily:e}})}createText(e){return new t.Text(e)}}exports.DefaultDisplayObjectFactory=a;
2
+ //# sourceMappingURL=index9.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index9.cjs","sources":["../src/factory.ts"],"sourcesContent":["import { Sprite, Container, Graphics, BitmapText, Text } from 'pixi.js';\nimport type { Texture, TextOptions } from 'pixi.js';\n\n/**\n * Display object factory interface.\n * Satisfies Constitution VI: \"Display object creation MUST go through\n * factory functions, making it easy to replace with Mocks in tests.\"\n */\nexport interface DisplayObjectFactory {\n /** Create a sprite */\n createSprite(texture?: Texture): Sprite;\n\n /** Create a container */\n createContainer(): Container;\n\n /** Create a graphics object */\n createGraphics(): Graphics;\n\n /**\n * Create a bitmap text (default text approach).\n * Satisfies Constitution IV: \"Text rendering MUST use BitmapText\n * or pre-rendering strategy.\"\n */\n createBitmapText(fontName: string, text: string): BitmapText;\n\n /**\n * Create a dynamic text (for multilingual or runtime-rendered text).\n * Only use when BitmapText is not suitable.\n */\n createText(options: TextOptions): Text;\n}\n\n/**\n * Default factory implementation that directly calls PixiJS constructors.\n */\nexport class DefaultDisplayObjectFactory implements DisplayObjectFactory {\n createSprite(texture?: Texture): Sprite {\n return new Sprite(texture);\n }\n\n createContainer(): Container {\n return new Container();\n }\n\n createGraphics(): Graphics {\n return new Graphics();\n }\n\n createBitmapText(fontName: string, text: string): BitmapText {\n return new BitmapText({\n text,\n style: { fontFamily: fontName },\n });\n }\n\n createText(options: TextOptions): Text {\n return new Text(options);\n }\n}\n"],"names":["DefaultDisplayObjectFactory","texture","Sprite","Container","Graphics","fontName","text","BitmapText","options","Text"],"mappings":"2GAmCO,MAAMA,CAA4D,CACvE,aAAaC,EAA2B,CACtC,OAAO,IAAIC,EAAAA,OAAOD,CAAO,CAC3B,CAEA,iBAA6B,CAC3B,OAAO,IAAIE,EAAAA,SACb,CAEA,gBAA2B,CACzB,OAAO,IAAIC,EAAAA,QACb,CAEA,iBAAiBC,EAAkBC,EAA0B,CAC3D,OAAO,IAAIC,EAAAA,WAAW,CACpB,KAAAD,EACA,MAAO,CAAE,WAAYD,CAAA,CAAS,CAC/B,CACH,CAEA,WAAWG,EAA4B,CACrC,OAAO,IAAIC,EAAAA,KAAKD,CAAO,CACzB,CACF"}
package/dist/index9.js ADDED
@@ -0,0 +1,25 @@
1
+ import { Sprite as r, Container as a, Graphics as n, BitmapText as i, Text as c } from "pixi.js";
2
+ class s {
3
+ createSprite(e) {
4
+ return new r(e);
5
+ }
6
+ createContainer() {
7
+ return new a();
8
+ }
9
+ createGraphics() {
10
+ return new n();
11
+ }
12
+ createBitmapText(e, t) {
13
+ return new i({
14
+ text: t,
15
+ style: { fontFamily: e }
16
+ });
17
+ }
18
+ createText(e) {
19
+ return new c(e);
20
+ }
21
+ }
22
+ export {
23
+ s as DefaultDisplayObjectFactory
24
+ };
25
+ //# sourceMappingURL=index9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index9.js","sources":["../src/factory.ts"],"sourcesContent":["import { Sprite, Container, Graphics, BitmapText, Text } from 'pixi.js';\nimport type { Texture, TextOptions } from 'pixi.js';\n\n/**\n * Display object factory interface.\n * Satisfies Constitution VI: \"Display object creation MUST go through\n * factory functions, making it easy to replace with Mocks in tests.\"\n */\nexport interface DisplayObjectFactory {\n /** Create a sprite */\n createSprite(texture?: Texture): Sprite;\n\n /** Create a container */\n createContainer(): Container;\n\n /** Create a graphics object */\n createGraphics(): Graphics;\n\n /**\n * Create a bitmap text (default text approach).\n * Satisfies Constitution IV: \"Text rendering MUST use BitmapText\n * or pre-rendering strategy.\"\n */\n createBitmapText(fontName: string, text: string): BitmapText;\n\n /**\n * Create a dynamic text (for multilingual or runtime-rendered text).\n * Only use when BitmapText is not suitable.\n */\n createText(options: TextOptions): Text;\n}\n\n/**\n * Default factory implementation that directly calls PixiJS constructors.\n */\nexport class DefaultDisplayObjectFactory implements DisplayObjectFactory {\n createSprite(texture?: Texture): Sprite {\n return new Sprite(texture);\n }\n\n createContainer(): Container {\n return new Container();\n }\n\n createGraphics(): Graphics {\n return new Graphics();\n }\n\n createBitmapText(fontName: string, text: string): BitmapText {\n return new BitmapText({\n text,\n style: { fontFamily: fontName },\n });\n }\n\n createText(options: TextOptions): Text {\n return new Text(options);\n }\n}\n"],"names":["DefaultDisplayObjectFactory","texture","Sprite","Container","Graphics","fontName","text","BitmapText","options","Text"],"mappings":";AAmCO,MAAMA,EAA4D;AAAA,EACvE,aAAaC,GAA2B;AACtC,WAAO,IAAIC,EAAOD,CAAO;AAAA,EAC3B;AAAA,EAEA,kBAA6B;AAC3B,WAAO,IAAIE,EAAA;AAAA,EACb;AAAA,EAEA,iBAA2B;AACzB,WAAO,IAAIC,EAAA;AAAA,EACb;AAAA,EAEA,iBAAiBC,GAAkBC,GAA0B;AAC3D,WAAO,IAAIC,EAAW;AAAA,MACpB,MAAAD;AAAA,MACA,OAAO,EAAE,YAAYD,EAAA;AAAA,IAAS,CAC/B;AAAA,EACH;AAAA,EAEA,WAAWG,GAA4B;AACrC,WAAO,IAAIC,EAAKD,CAAO;AAAA,EACzB;AACF;"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@ksgames26/core",
3
+ "version": "0.1.0",
4
+ "description": "Core package for PixiJS game framework",
5
+ "type": "module",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/your-org/pixijs-game-framework.git",
9
+ "directory": "packages/core"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/your-org/pixijs-game-framework/issues"
13
+ },
14
+ "homepage": "https://github.com/your-org/pixijs-game-framework/tree/main/packages/core#readme",
15
+ "keywords": [
16
+ "pixi",
17
+ "pixijs",
18
+ "game",
19
+ "framework",
20
+ "core"
21
+ ],
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "require": "./dist/index.cjs"
30
+ }
31
+ },
32
+ "sideEffects": false,
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "publishConfig": {
37
+ "access": "public"
38
+ },
39
+ "peerDependencies": {
40
+ "pixi.js": ">=8.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "pixi.js": "^8.13.0"
44
+ },
45
+ "scripts": {
46
+ "build": "vite build",
47
+ "dev": "vite build --watch",
48
+ "lint": "eslint src/",
49
+ "test": "vitest run",
50
+ "clean": "rm -rf dist",
51
+ "typecheck": "tsc --noEmit"
52
+ }
53
+ }