@oidoid/void 0.1.0-4 → 0.1.0-7
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/meta.json +1 -0
- package/dist/package.json +66 -0
- package/dist/public/favicon/favicon16.png +0 -0
- package/dist/public/favicon/favicon16.webp +0 -0
- package/dist/public/favicon/favicon192.png +0 -0
- package/dist/public/favicon/favicon192.webp +0 -0
- package/dist/public/favicon/favicon32.png +0 -0
- package/dist/public/favicon/favicon32.webp +0 -0
- package/dist/public/favicon/favicon48.png +0 -0
- package/dist/public/favicon/favicon48.webp +0 -0
- package/dist/public/favicon/favicon64.png +0 -0
- package/dist/public/favicon/favicon64.webp +0 -0
- package/dist/public/index.js +98 -0
- package/dist/public/index.js.map +7 -0
- package/dist/public/preload-atlas.png +0 -0
- package/dist/public/preload-atlas.webp +0 -0
- package/dist/public/void-v0.1.0-6+20251020.7cdf98d.html +111 -0
- package/dist/public/void-v0.1.0-6+20251020.e4e9eef.html +111 -0
- package/dist/public/void-v0.1.0-7+20251021.7cdf98d.html +111 -0
- package/dist/schema/config-file.d.ts +32 -0
- package/dist/schema/config-file.js +41 -0
- package/dist/schema/config-file.js.map +1 -0
- package/dist/schema/config-file.v0.json +68 -0
- package/dist/src/audio.d.ts +7 -0
- package/dist/src/audio.js +25 -0
- package/dist/src/audio.js.map +1 -0
- package/dist/src/demo/assets/manifest.json +41 -0
- package/dist/src/demo/assets/preload-atlas.json +193 -0
- package/dist/src/demo/ents/clock-ent.d.ts +11 -0
- package/dist/src/demo/ents/clock-ent.js +26 -0
- package/dist/src/demo/ents/clock-ent.js.map +1 -0
- package/dist/src/demo/ents/render-toggle-ent.d.ts +12 -0
- package/dist/src/demo/ents/render-toggle-ent.js +41 -0
- package/dist/src/demo/ents/render-toggle-ent.js.map +1 -0
- package/dist/src/demo/ents/work-counter-ent.d.ts +10 -0
- package/dist/src/demo/ents/work-counter-ent.js +20 -0
- package/dist/src/demo/ents/work-counter-ent.js.map +1 -0
- package/dist/src/demo/game.d.ts +12 -0
- package/dist/src/demo/game.js +135 -0
- package/dist/src/demo/game.js.map +1 -0
- package/dist/src/demo/index.d.ts +1 -0
- package/dist/src/demo/index.js +8 -0
- package/dist/src/demo/index.js.map +1 -0
- package/dist/src/demo/tsconfig.json +15 -0
- package/dist/src/demo/types/tag.d.ts +2 -0
- package/dist/src/demo/types/tag.js +2 -0
- package/dist/src/demo/types/tag.js.map +1 -0
- package/dist/src/demo/void.json +11 -0
- package/dist/src/ents/button-ent.d.ts +39 -0
- package/dist/src/ents/button-ent.js +128 -0
- package/dist/src/ents/button-ent.js.map +1 -0
- package/dist/src/ents/cursor-ent.d.ts +18 -0
- package/dist/src/ents/cursor-ent.js +63 -0
- package/dist/src/ents/cursor-ent.js.map +1 -0
- package/dist/src/ents/ent.d.ts +7 -0
- package/dist/src/ents/ent.js +2 -0
- package/dist/src/ents/ent.js.map +1 -0
- package/dist/src/ents/follow-cam-ent.d.ts +25 -0
- package/dist/src/ents/follow-cam-ent.js +87 -0
- package/dist/src/ents/follow-cam-ent.js.map +1 -0
- package/dist/src/ents/nine-patch-ent.d.ts +43 -0
- package/dist/src/ents/nine-patch-ent.js +143 -0
- package/dist/src/ents/nine-patch-ent.js.map +1 -0
- package/dist/src/ents/text-ent.d.ts +23 -0
- package/dist/src/ents/text-ent.js +109 -0
- package/dist/src/ents/text-ent.js.map +1 -0
- package/dist/src/ents/zoo.d.ts +17 -0
- package/dist/src/ents/zoo.js +45 -0
- package/dist/src/ents/zoo.js.map +1 -0
- package/dist/src/graphics/atlas-parser.d.ts +4 -0
- package/dist/src/graphics/atlas-parser.js +27 -0
- package/dist/src/graphics/atlas-parser.js.map +1 -0
- package/dist/src/graphics/atlas.d.ts +49 -0
- package/dist/src/graphics/atlas.js +7 -0
- package/dist/src/graphics/atlas.js.map +1 -0
- package/dist/src/graphics/cam.d.ts +89 -0
- package/dist/src/graphics/cam.js +220 -0
- package/dist/src/graphics/cam.js.map +1 -0
- package/dist/src/graphics/gl.d.ts +24 -0
- package/dist/src/graphics/gl.js +70 -0
- package/dist/src/graphics/gl.js.map +1 -0
- package/dist/src/graphics/layer.d.ts +21 -0
- package/dist/src/graphics/layer.js +23 -0
- package/dist/src/graphics/layer.js.map +1 -0
- package/dist/src/graphics/renderer.d.ts +36 -0
- package/dist/src/graphics/renderer.js +180 -0
- package/dist/src/graphics/renderer.js.map +1 -0
- package/dist/src/graphics/sprite-frag.glsl.d.ts +1 -0
- package/dist/src/graphics/sprite-frag.glsl.js +35 -0
- package/dist/src/graphics/sprite-frag.glsl.js.map +1 -0
- package/dist/src/graphics/sprite-vert.glsl.d.ts +1 -0
- package/dist/src/graphics/sprite-vert.glsl.js +68 -0
- package/dist/src/graphics/sprite-vert.glsl.js.map +1 -0
- package/dist/src/graphics/sprite.d.ts +108 -0
- package/dist/src/graphics/sprite.js +301 -0
- package/dist/src/graphics/sprite.js.map +1 -0
- package/dist/src/index.d.ts +30 -0
- package/dist/src/index.js +33 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/input/context-menu.d.ts +8 -0
- package/dist/src/input/context-menu.js +25 -0
- package/dist/src/input/context-menu.js.map +1 -0
- package/dist/src/input/gamepad.d.ts +18 -0
- package/dist/src/input/gamepad.js +49 -0
- package/dist/src/input/gamepad.js.map +1 -0
- package/dist/src/input/input.d.ts +148 -0
- package/dist/src/input/input.js +383 -0
- package/dist/src/input/input.js.map +1 -0
- package/dist/src/input/keyboard.d.ts +17 -0
- package/dist/src/input/keyboard.js +46 -0
- package/dist/src/input/keyboard.js.map +1 -0
- package/dist/src/input/pointer.d.ts +53 -0
- package/dist/src/input/pointer.js +162 -0
- package/dist/src/input/pointer.js.map +1 -0
- package/dist/src/input/wheel.d.ts +12 -0
- package/dist/src/input/wheel.js +30 -0
- package/dist/src/input/wheel.js.map +1 -0
- package/dist/src/looper.d.ts +17 -0
- package/dist/src/looper.js +51 -0
- package/dist/src/looper.js.map +1 -0
- package/dist/src/mem/pool.d.ts +31 -0
- package/dist/src/mem/pool.js +98 -0
- package/dist/src/mem/pool.js.map +1 -0
- package/dist/src/random/random.d.ts +8 -0
- package/dist/src/random/random.js +23 -0
- package/dist/src/random/random.js.map +1 -0
- package/dist/src/storage/local-storage.d.ts +3 -0
- package/dist/src/storage/local-storage.js +11 -0
- package/dist/src/storage/local-storage.js.map +1 -0
- package/dist/src/text/font.d.ts +6 -0
- package/dist/src/text/font.js +20 -0
- package/dist/src/text/font.js.map +1 -0
- package/dist/src/text/mem-prop-5x6.json +573 -0
- package/dist/src/text/text-layout.d.ts +19 -0
- package/dist/src/text/text-layout.js +85 -0
- package/dist/src/text/text-layout.js.map +1 -0
- package/dist/src/tsconfig.json +15 -0
- package/dist/src/types/geo.d.ts +38 -0
- package/dist/src/types/geo.js +61 -0
- package/dist/src/types/geo.js.map +1 -0
- package/dist/src/types/json.d.ts +31 -0
- package/dist/src/types/json.js +2 -0
- package/dist/src/types/json.js.map +1 -0
- package/dist/src/types/time.d.ts +19 -0
- package/dist/src/types/time.js +10 -0
- package/dist/src/types/time.js.map +1 -0
- package/dist/src/types/void-version.d.ts +7 -0
- package/dist/src/types/void-version.js +2 -0
- package/dist/src/types/void-version.js.map +1 -0
- package/dist/src/utils/async-util.d.ts +11 -0
- package/dist/src/utils/async-util.js +36 -0
- package/dist/src/utils/async-util.js.map +1 -0
- package/dist/src/utils/canvas-util.d.ts +7 -0
- package/dist/src/utils/canvas-util.js +128 -0
- package/dist/src/utils/canvas-util.js.map +1 -0
- package/dist/src/utils/color-util.d.ts +1 -0
- package/dist/src/utils/color-util.js +4 -0
- package/dist/src/utils/color-util.js.map +1 -0
- package/dist/src/utils/debug.d.ts +19 -0
- package/dist/src/utils/debug.js +35 -0
- package/dist/src/utils/debug.js.map +1 -0
- package/dist/src/utils/delay-interval.d.ts +7 -0
- package/dist/src/utils/delay-interval.js +29 -0
- package/dist/src/utils/delay-interval.js.map +1 -0
- package/dist/src/utils/dom-util.d.ts +3 -0
- package/dist/src/utils/dom-util.js +29 -0
- package/dist/src/utils/dom-util.js.map +1 -0
- package/dist/src/utils/fetch-util.d.ts +3 -0
- package/dist/src/utils/fetch-util.js +24 -0
- package/dist/src/utils/fetch-util.js.map +1 -0
- package/dist/src/utils/math.d.ts +6 -0
- package/dist/src/utils/math.js +18 -0
- package/dist/src/utils/math.js.map +1 -0
- package/dist/src/utils/vibrate.d.ts +1 -0
- package/dist/src/utils/vibrate.js +4 -0
- package/dist/src/utils/vibrate.js.map +1 -0
- package/dist/src/void.d.ts +48 -0
- package/dist/src/void.js +102 -0
- package/dist/src/void.js.map +1 -0
- package/dist/tools/atlas-pack/aseprite.d.ts +58 -0
- package/dist/tools/atlas-pack/aseprite.js +16 -0
- package/dist/tools/atlas-pack/aseprite.js.map +1 -0
- package/dist/tools/atlas-pack/atlas-json-parser.d.ts +21 -0
- package/dist/tools/atlas-pack/atlas-json-parser.js +116 -0
- package/dist/tools/atlas-pack/atlas-json-parser.js.map +1 -0
- package/dist/tools/atlas-pack/atlas-pack.d.ts +2 -0
- package/dist/tools/atlas-pack/atlas-pack.js +22 -0
- package/dist/tools/atlas-pack/atlas-pack.js.map +1 -0
- package/dist/tools/bundle/bundle.d.ts +3 -0
- package/dist/tools/bundle/bundle.js +48 -0
- package/dist/tools/bundle/bundle.js.map +1 -0
- package/dist/tools/bundle/html-plugin.d.ts +3 -0
- package/dist/tools/bundle/html-plugin.js +90 -0
- package/dist/tools/bundle/html-plugin.js.map +1 -0
- package/dist/tools/tsconfig-base.json +48 -0
- package/dist/tools/tsconfig.json +19 -0
- package/dist/tools/types/config.d.ts +27 -0
- package/dist/tools/types/config.js +31 -0
- package/dist/tools/types/config.js.map +1 -0
- package/dist/tools/types/package-json.d.ts +4 -0
- package/dist/tools/types/package-json.js +2 -0
- package/dist/tools/types/package-json.js.map +1 -0
- package/dist/tools/utils/argv.d.ts +12 -0
- package/dist/tools/utils/argv.js +19 -0
- package/dist/tools/utils/argv.js.map +1 -0
- package/dist/tools/utils/exec.d.ts +3 -0
- package/dist/tools/utils/exec.js +15 -0
- package/dist/tools/utils/exec.js.map +1 -0
- package/dist/tools/utils/file-util.d.ts +1 -0
- package/dist/tools/utils/file-util.js +13 -0
- package/dist/tools/utils/file-util.js.map +1 -0
- package/dist/tools/utils/html-parser.d.ts +1 -0
- package/dist/tools/utils/html-parser.js +10 -0
- package/dist/tools/utils/html-parser.js.map +1 -0
- package/dist/tools/void.d.ts +15 -0
- package/dist/tools/void.js +31 -0
- package/dist/tools/void.js.map +1 -0
- package/package.json +31 -41
- package/readme.md +1 -1
- package/schema/config-file.test.ts +55 -0
- package/schema/config-file.ts +69 -0
- package/schema/config-file.v0.json +68 -0
- package/tools/atlas-pack/aseprite.ts +60 -0
- package/tools/atlas-pack/atlas-json-parser.test.ts +780 -0
- package/tools/atlas-pack/atlas-json-parser.ts +159 -0
- package/tools/atlas-pack/atlas-pack.ts +51 -0
- package/tools/bundle/bundle.ts +64 -0
- package/tools/bundle/html-plugin.ts +135 -0
- package/tools/types/config.ts +65 -0
- package/tools/types/package-json.ts +4 -0
- package/tools/utils/argv.test.ts +41 -0
- package/tools/utils/argv.ts +29 -0
- package/tools/utils/exec.ts +22 -0
- package/tools/utils/file-util.ts +11 -0
- package/tools/utils/html-parser.ts +9 -0
- package/tools/void.ts +55 -0
- package/dist/atlas/anim.d.ts +0 -30
- package/dist/atlas/anim.js +0 -16
- package/dist/atlas/anim.js.map +0 -1
- package/dist/atlas/aseprite.d.ts +0 -37
- package/dist/atlas/aseprite.js +0 -2
- package/dist/atlas/aseprite.js.map +0 -1
- package/dist/atlas/atlas-parser.d.ts +0 -52
- package/dist/atlas/atlas-parser.js +0 -109
- package/dist/atlas/atlas-parser.js.map +0 -1
- package/dist/atlas/atlas.d.ts +0 -4
- package/dist/atlas/atlas.js +0 -2
- package/dist/atlas/atlas.js.map +0 -1
- package/dist/audio/synth.d.ts +0 -4
- package/dist/audio/synth.js +0 -21
- package/dist/audio/synth.js.map +0 -1
- package/dist/graphics/bitmap.d.ts +0 -14
- package/dist/graphics/bitmap.js +0 -14
- package/dist/graphics/bitmap.js.map +0 -1
- package/dist/graphics/cam.d.ts +0 -16
- package/dist/graphics/cam.js +0 -42
- package/dist/graphics/cam.js.map +0 -1
- package/dist/graphics/frag.glsl.d.ts +0 -1
- package/dist/graphics/frag.glsl.js +0 -15
- package/dist/graphics/frag.glsl.js.map +0 -1
- package/dist/graphics/frame-listener.d.ts +0 -16
- package/dist/graphics/frame-listener.js +0 -83
- package/dist/graphics/frame-listener.js.map +0 -1
- package/dist/graphics/renderer.d.ts +0 -12
- package/dist/graphics/renderer.js +0 -184
- package/dist/graphics/renderer.js.map +0 -1
- package/dist/graphics/vert.glsl.d.ts +0 -1
- package/dist/graphics/vert.glsl.js +0 -46
- package/dist/graphics/vert.glsl.js.map +0 -1
- package/dist/index.d.ts +0 -31
- package/dist/index.js +0 -79
- package/dist/index.js.map +0 -1
- package/dist/input/gamepad-poller.d.ts +0 -8
- package/dist/input/gamepad-poller.js +0 -38
- package/dist/input/gamepad-poller.js.map +0 -1
- package/dist/input/input.d.ts +0 -44
- package/dist/input/input.js +0 -175
- package/dist/input/input.js.map +0 -1
- package/dist/input/keyboard-poller.d.ts +0 -7
- package/dist/input/keyboard-poller.js +0 -30
- package/dist/input/keyboard-poller.js.map +0 -1
- package/dist/input/pointer-poller.d.ts +0 -12
- package/dist/input/pointer-poller.js +0 -67
- package/dist/input/pointer-poller.js.map +0 -1
- package/dist/sprite/sprite.d.ts +0 -51
- package/dist/sprite/sprite.js +0 -161
- package/dist/sprite/sprite.js.map +0 -1
- package/dist/storage/json-storage.d.ts +0 -4
- package/dist/storage/json-storage.js +0 -13
- package/dist/storage/json-storage.js.map +0 -1
- package/dist/test/tsconfig.json +0 -14
- package/dist/text/font.d.ts +0 -6
- package/dist/text/font.js +0 -18
- package/dist/text/font.js.map +0 -1
- package/dist/text/text-layout.d.ts +0 -11
- package/dist/text/text-layout.js +0 -73
- package/dist/text/text-layout.js.map +0 -1
- package/dist/tsconfig.json +0 -13
- package/dist/types/2d.d.ts +0 -9
- package/dist/types/2d.js +0 -2
- package/dist/types/2d.js.map +0 -1
- package/dist/void.js +0 -60
- package/dist/void.js.map +0 -7
- package/dist/void.meta.json +0 -289
- package/src/atlas/anim.js +0 -17
- package/tools/atlas-parser.js +0 -120
- package/tools/void.js +0 -143
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Zoo } from './ents/zoo.ts';
|
|
2
|
+
import type { Atlas, AtlasJSON, TagFormat } from './graphics/atlas.ts';
|
|
3
|
+
import { Cam } from './graphics/cam.ts';
|
|
4
|
+
import { Renderer } from './graphics/renderer.ts';
|
|
5
|
+
import { Sprite } from './graphics/sprite.ts';
|
|
6
|
+
import { type DefaultButton, Input } from './input/input.ts';
|
|
7
|
+
import { Looper } from './looper.ts';
|
|
8
|
+
import { Pool, type PoolOpts } from './mem/pool.ts';
|
|
9
|
+
import type { WH } from './types/geo.ts';
|
|
10
|
+
import type { Millis } from './types/time.ts';
|
|
11
|
+
export type VoidOpts<out Tag extends TagFormat> = {
|
|
12
|
+
preloadAtlas?: {
|
|
13
|
+
image: HTMLImageElement;
|
|
14
|
+
json: AtlasJSON;
|
|
15
|
+
} | undefined;
|
|
16
|
+
backgroundRGBA?: number;
|
|
17
|
+
canvas?: HTMLCanvasElement | undefined;
|
|
18
|
+
minWH?: WH | undefined;
|
|
19
|
+
input?: 'Custom' | 'Default' | undefined;
|
|
20
|
+
mode?: 'Int' | 'Fraction' | undefined;
|
|
21
|
+
poll?: {
|
|
22
|
+
delay?: (() => Millis) | undefined;
|
|
23
|
+
period: Millis;
|
|
24
|
+
} | undefined;
|
|
25
|
+
sprites?: Partial<Omit<PoolOpts<Sprite<Tag>>, 'alloc' | 'allocBytes'>> | undefined;
|
|
26
|
+
};
|
|
27
|
+
export declare class Void<out Tag extends TagFormat, Button extends string = DefaultButton> {
|
|
28
|
+
#private;
|
|
29
|
+
readonly cam: Cam;
|
|
30
|
+
readonly canvas: HTMLCanvasElement;
|
|
31
|
+
readonly input: Input<Button>;
|
|
32
|
+
readonly preload: Atlas;
|
|
33
|
+
readonly renderer: Renderer;
|
|
34
|
+
readonly sprites: Pool<Sprite<Tag>>;
|
|
35
|
+
readonly zoo: Zoo<Tag>;
|
|
36
|
+
readonly looper: Looper;
|
|
37
|
+
constructor(opts: Readonly<VoidOpts<Tag>>);
|
|
38
|
+
onAllocSprite(pool: Pool<Sprite<Tag>>): Sprite<Tag>;
|
|
39
|
+
onEvent(): void;
|
|
40
|
+
/** update input, update canvas, update cam, update world, then render. */
|
|
41
|
+
onFrame(millis: Millis): void;
|
|
42
|
+
onLoop(millis: Millis): void;
|
|
43
|
+
onPoll(): void;
|
|
44
|
+
onResize(): void;
|
|
45
|
+
register(op: 'add' | 'remove'): Promise<void>;
|
|
46
|
+
requestFrame(force?: 'Force' | undefined): void;
|
|
47
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
48
|
+
}
|
package/dist/src/void.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { Zoo } from "./ents/zoo.js";
|
|
2
|
+
import { parseAtlas } from "./graphics/atlas-parser.js";
|
|
3
|
+
import { Cam } from "./graphics/cam.js";
|
|
4
|
+
import { Renderer } from "./graphics/renderer.js";
|
|
5
|
+
import { drawableBytes, Sprite } from "./graphics/sprite.js";
|
|
6
|
+
import { Input } from "./input/input.js";
|
|
7
|
+
import { Looper } from "./looper.js";
|
|
8
|
+
import { Pool } from "./mem/pool.js";
|
|
9
|
+
import { initCanvas } from "./utils/canvas-util.js";
|
|
10
|
+
import { DelayInterval } from "./utils/delay-interval.js";
|
|
11
|
+
import { initBody, initMetaViewport } from "./utils/dom-util.js";
|
|
12
|
+
import { loadImage } from "./utils/fetch-util.js";
|
|
13
|
+
export class Void {
|
|
14
|
+
cam = new Cam();
|
|
15
|
+
canvas;
|
|
16
|
+
input;
|
|
17
|
+
preload;
|
|
18
|
+
renderer;
|
|
19
|
+
sprites;
|
|
20
|
+
zoo = new Zoo();
|
|
21
|
+
looper = new Looper();
|
|
22
|
+
#poll;
|
|
23
|
+
#preloadAtlasImage;
|
|
24
|
+
// may trigger an initial force update.
|
|
25
|
+
#resizeObserver = new ResizeObserver(() => this.onResize());
|
|
26
|
+
constructor(opts) {
|
|
27
|
+
if (opts.poll != null)
|
|
28
|
+
this.#poll = new DelayInterval(opts.poll.delay ?? (() => 0), opts.poll.period, () => this.onPoll());
|
|
29
|
+
initMetaViewport();
|
|
30
|
+
this.canvas = initCanvas(opts.canvas, opts.mode ?? 'Int');
|
|
31
|
+
initBody(this.canvas, opts.backgroundRGBA ?? 0x000000ff);
|
|
32
|
+
if (opts.minWH)
|
|
33
|
+
this.cam.minWH = opts.minWH;
|
|
34
|
+
this.cam.mode = opts.mode ?? 'Int';
|
|
35
|
+
this.cam.update(this.canvas);
|
|
36
|
+
this.input = new Input(this.cam, this.canvas);
|
|
37
|
+
if (opts.input !== 'Custom')
|
|
38
|
+
this.input.mapDefault();
|
|
39
|
+
this.input.onEvent = () => this.onEvent();
|
|
40
|
+
if (opts.preloadAtlas)
|
|
41
|
+
this.#preloadAtlasImage = opts.preloadAtlas.image;
|
|
42
|
+
this.preload = opts.preloadAtlas
|
|
43
|
+
? parseAtlas(opts.preloadAtlas.json)
|
|
44
|
+
: { anim: {}, celXYWH: [], tags: [] };
|
|
45
|
+
this.renderer = new Renderer(this.preload ?? {}, this.canvas, this.looper);
|
|
46
|
+
this.sprites = new Pool({
|
|
47
|
+
alloc: pool => this.onAllocSprite(pool),
|
|
48
|
+
allocBytes: drawableBytes,
|
|
49
|
+
minPages: opts.sprites?.minPages ?? 3,
|
|
50
|
+
pageBlocks: opts.sprites?.pageBlocks ?? 1000
|
|
51
|
+
});
|
|
52
|
+
this.looper.onFrame = millis => this.onFrame(millis);
|
|
53
|
+
}
|
|
54
|
+
onAllocSprite(pool) {
|
|
55
|
+
return new Sprite(pool, 0, this.preload, this.looper);
|
|
56
|
+
}
|
|
57
|
+
onEvent() {
|
|
58
|
+
this.requestFrame('Force');
|
|
59
|
+
}
|
|
60
|
+
/** update input, update canvas, update cam, update world, then render. */
|
|
61
|
+
onFrame(millis) {
|
|
62
|
+
if (document.hidden)
|
|
63
|
+
return;
|
|
64
|
+
this.input.update(millis);
|
|
65
|
+
this.requestFrame(); // request frame before in case loop cancels.
|
|
66
|
+
this.onLoop(millis);
|
|
67
|
+
this.cam.postupdate();
|
|
68
|
+
}
|
|
69
|
+
// biome-ignore lint/correctness/noUnusedFunctionParameters:;
|
|
70
|
+
onLoop(millis) { }
|
|
71
|
+
onPoll() {
|
|
72
|
+
this.requestFrame('Force');
|
|
73
|
+
}
|
|
74
|
+
onResize() {
|
|
75
|
+
this.requestFrame('Force'); // force cam reeval.
|
|
76
|
+
}
|
|
77
|
+
async register(op) {
|
|
78
|
+
this.input.register(op);
|
|
79
|
+
this.renderer.register(op);
|
|
80
|
+
this.looper.register(op);
|
|
81
|
+
if (!this.canvas.parentElement)
|
|
82
|
+
throw Error('no canvas parent');
|
|
83
|
+
if (op === 'add')
|
|
84
|
+
this.#resizeObserver.observe(this.canvas.parentElement);
|
|
85
|
+
else
|
|
86
|
+
this.#resizeObserver.unobserve(this.canvas.parentElement);
|
|
87
|
+
if (op === 'add')
|
|
88
|
+
this.looper.requestFrame();
|
|
89
|
+
this.#poll?.register(op);
|
|
90
|
+
if (this.#preloadAtlasImage)
|
|
91
|
+
await loadImage(this.#preloadAtlasImage);
|
|
92
|
+
this.renderer.load(this.#preloadAtlasImage);
|
|
93
|
+
}
|
|
94
|
+
requestFrame(force) {
|
|
95
|
+
if (force || this.renderer.always || this.input.anyOn || this.input.gamepad)
|
|
96
|
+
this.looper.requestFrame();
|
|
97
|
+
}
|
|
98
|
+
async [Symbol.asyncDispose]() {
|
|
99
|
+
await this.register('remove');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=void.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"void.js","sourceRoot":"","sources":["../../src/void.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { TagFormat } from '../../src/graphics/atlas.ts';
|
|
2
|
+
import type { Box, WH } from '../../src/types/geo.ts';
|
|
3
|
+
/** https://github.com/aseprite/aseprite/blob/master/docs/ase-file-specs.md */
|
|
4
|
+
export type Aseprite = {
|
|
5
|
+
meta: AsepriteMeta;
|
|
6
|
+
frames: AsepriteFrameMap;
|
|
7
|
+
};
|
|
8
|
+
export type AsepriteFrameMap = {
|
|
9
|
+
[tag: AsepriteFrameTag]: AsepriteFrame;
|
|
10
|
+
};
|
|
11
|
+
export type AsepriteMeta = {
|
|
12
|
+
/** `--list-tags`. */
|
|
13
|
+
frameTags: AsepriteTagSpan[];
|
|
14
|
+
size: WH;
|
|
15
|
+
/** `--list-slices`. */
|
|
16
|
+
slices: AsepriteSlice[];
|
|
17
|
+
};
|
|
18
|
+
/** `--filename-format='{title}--{tag}--{frame}'`. */
|
|
19
|
+
export type AsepriteFrameTag = `${TagFormat}--${bigint}`;
|
|
20
|
+
export type AsepriteFrame = {
|
|
21
|
+
/** positive animation length in milliseconds. */
|
|
22
|
+
duration: number;
|
|
23
|
+
/** bounds including padding. */
|
|
24
|
+
frame: Box;
|
|
25
|
+
/** WH without padding. */
|
|
26
|
+
sourceSize: WH;
|
|
27
|
+
};
|
|
28
|
+
export type AsepriteTagSpan = {
|
|
29
|
+
direction: AsepriteDirection | string;
|
|
30
|
+
name: TagFormat | string;
|
|
31
|
+
from: number;
|
|
32
|
+
/** inclusive ending index, possibly equal to from. */
|
|
33
|
+
to: number;
|
|
34
|
+
};
|
|
35
|
+
export type AsepriteSlice = {
|
|
36
|
+
/** '#ff0000ff' is hitbox, '#00ff00ff' is hurtbox, '#0000ffff is both. */
|
|
37
|
+
color: string;
|
|
38
|
+
name: TagFormat | string;
|
|
39
|
+
keys: {
|
|
40
|
+
bounds: Box;
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
export type AsepriteDirection = (typeof AsepriteDirection)[keyof typeof AsepriteDirection];
|
|
44
|
+
export declare const AsepriteDirection: {
|
|
45
|
+
/** animate from start to end; when looping, return to start. */
|
|
46
|
+
readonly Forward: "forward";
|
|
47
|
+
/** animate from end to start; when looping, return to end. */
|
|
48
|
+
readonly Reverse: "reverse";
|
|
49
|
+
/**
|
|
50
|
+
* animate from start to end - 1 or start, whichever is greater; when
|
|
51
|
+
* looping, change direction (initially, end to start + 1 or end, whichever
|
|
52
|
+
* is lesser. a traversal from start to end - 1 then end to start + 1 is
|
|
53
|
+
* considered a complete loop.
|
|
54
|
+
*/
|
|
55
|
+
readonly PingPong: "pingpong";
|
|
56
|
+
/** like pingpong but start from end - 1 or start, whichever is greater. */
|
|
57
|
+
readonly PingPongReverse: "pingpong_reverse";
|
|
58
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const AsepriteDirection = {
|
|
2
|
+
/** animate from start to end; when looping, return to start. */
|
|
3
|
+
Forward: 'forward',
|
|
4
|
+
/** animate from end to start; when looping, return to end. */
|
|
5
|
+
Reverse: 'reverse',
|
|
6
|
+
/**
|
|
7
|
+
* animate from start to end - 1 or start, whichever is greater; when
|
|
8
|
+
* looping, change direction (initially, end to start + 1 or end, whichever
|
|
9
|
+
* is lesser. a traversal from start to end - 1 then end to start + 1 is
|
|
10
|
+
* considered a complete loop.
|
|
11
|
+
*/
|
|
12
|
+
PingPong: 'pingpong',
|
|
13
|
+
/** like pingpong but start from end - 1 or start, whichever is greater. */
|
|
14
|
+
PingPongReverse: 'pingpong_reverse'
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=aseprite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aseprite.js","sourceRoot":"","sources":["../../../tools/atlas-pack/aseprite.ts"],"names":[],"mappings":"AA6CA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,gEAAgE;IAChE,OAAO,EAAE,SAAS;IAClB,8DAA8D;IAC9D,OAAO,EAAE,SAAS;IAClB;;;;;OAKG;IACH,QAAQ,EAAE,UAAU;IACpB,2EAA2E;IAC3E,eAAe,EAAE,kBAAkB;CAC3B,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Anim, type AtlasJSON } from '../../src/graphics/atlas.ts';
|
|
2
|
+
import { type Box, type XY } from '../../src/types/geo.ts';
|
|
3
|
+
import { type Aseprite, type AsepriteFrame, type AsepriteFrameMap, type AsepriteSlice, type AsepriteTagSpan } from './aseprite.ts';
|
|
4
|
+
export declare function parseAtlasJSON(ase: Readonly<Aseprite>): AtlasJSON;
|
|
5
|
+
/** @internal */
|
|
6
|
+
export declare function parseAnim(id: number, span: Readonly<AsepriteTagSpan>, map: Readonly<AsepriteFrameMap>, slices: readonly Readonly<AsepriteSlice>[]): Anim;
|
|
7
|
+
/**
|
|
8
|
+
* every frame is guaranteed to be present for at least `celMillis`. cels are
|
|
9
|
+
* duplicated until cel duration is at least met. cels are unpacked until a full
|
|
10
|
+
* period is defined for the direction. no warns for overflowing past on second
|
|
11
|
+
* or uneven periods.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseAnimFrames(span: AsepriteTagSpan, map: AsepriteFrameMap): AsepriteFrame[];
|
|
15
|
+
/** @internal */
|
|
16
|
+
export declare function parseCel(frame: Readonly<AsepriteFrame>): XY;
|
|
17
|
+
/** @internal */
|
|
18
|
+
export declare function parseHitboxes(span: Readonly<AsepriteTagSpan>, slices: readonly Readonly<AsepriteSlice>[]): {
|
|
19
|
+
hitbox: Box | undefined;
|
|
20
|
+
hurtbox: Box | undefined;
|
|
21
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { animCels, animMillis, celMillis } from "../../src/graphics/atlas.js";
|
|
2
|
+
import { boxEq } from "../../src/types/geo.js";
|
|
3
|
+
import { AsepriteDirection } from "./aseprite.js";
|
|
4
|
+
export function parseAtlasJSON(ase) {
|
|
5
|
+
const anim = {};
|
|
6
|
+
const cels = [];
|
|
7
|
+
for (const span of ase.meta.frameTags) {
|
|
8
|
+
const tag = parseTag(span.name);
|
|
9
|
+
if (anim[tag])
|
|
10
|
+
throw Error(`atlas tag "${tag}" duplicate`);
|
|
11
|
+
const id = Object.keys(anim).length;
|
|
12
|
+
anim[tag] = parseAnim(id, span, ase.frames, ase.meta.slices);
|
|
13
|
+
for (const cel of parseAnimFrames(span, ase.frames).map(parseCel))
|
|
14
|
+
cels.push(cel.x, cel.y);
|
|
15
|
+
}
|
|
16
|
+
for (const slice of ase.meta.slices)
|
|
17
|
+
if (!anim[parseTag(slice.name)])
|
|
18
|
+
throw Error(`atlas hitbox "${slice.name}" has no animation`);
|
|
19
|
+
return { anim, celXY: cels };
|
|
20
|
+
}
|
|
21
|
+
/** @internal */
|
|
22
|
+
export function parseAnim(id, span, map, slices) {
|
|
23
|
+
const cels = parseAnimFrames(span, map);
|
|
24
|
+
if (!cels[0])
|
|
25
|
+
throw Error(`no atlas frame "${span.name}"`);
|
|
26
|
+
const { hitbox, hurtbox } = parseHitboxes(span, slices);
|
|
27
|
+
return {
|
|
28
|
+
cels: cels.length,
|
|
29
|
+
h: cels[0].sourceSize.h,
|
|
30
|
+
hitbox,
|
|
31
|
+
hurtbox,
|
|
32
|
+
id,
|
|
33
|
+
w: cels[0].sourceSize.w
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* every frame is guaranteed to be present for at least `celMillis`. cels are
|
|
38
|
+
* duplicated until cel duration is at least met. cels are unpacked until a full
|
|
39
|
+
* period is defined for the direction. no warns for overflowing past on second
|
|
40
|
+
* or uneven periods.
|
|
41
|
+
* @internal
|
|
42
|
+
*/
|
|
43
|
+
export function parseAnimFrames(span, map) {
|
|
44
|
+
const cels = [];
|
|
45
|
+
let animDuration = 0;
|
|
46
|
+
const len = span.to - span.from + 1;
|
|
47
|
+
const peak = len - 1;
|
|
48
|
+
const cycle = Math.max(1, 2 * peak);
|
|
49
|
+
const end = span.direction === AsepriteDirection.Forward ||
|
|
50
|
+
span.direction === AsepriteDirection.Reverse
|
|
51
|
+
? len
|
|
52
|
+
: cycle;
|
|
53
|
+
const indexByDir = {
|
|
54
|
+
forward: i => span.from + (i % len),
|
|
55
|
+
pingpong: i => span.from + peak - Math.abs((i % cycle) - peak),
|
|
56
|
+
pingpong_reverse: i => span.to - (peak - Math.abs((i % cycle) - peak)),
|
|
57
|
+
reverse: i => span.to - (i % len)
|
|
58
|
+
};
|
|
59
|
+
const frameIndex = indexByDir[span.direction];
|
|
60
|
+
for (let i = 0; i < end && cels.length < animCels && animDuration < animMillis; i++) {
|
|
61
|
+
const frameTag = `${span.name}--${frameIndex(i)}`;
|
|
62
|
+
const frame = map[frameTag];
|
|
63
|
+
if (!frame)
|
|
64
|
+
throw Error(`no atlas frame "${frameTag}"`);
|
|
65
|
+
for (let celDuration = 0; celDuration < frame.duration &&
|
|
66
|
+
cels.length < animCels &&
|
|
67
|
+
animDuration < animMillis; celDuration += celMillis, animDuration += celMillis) {
|
|
68
|
+
cels.push(frame);
|
|
69
|
+
if (span.from === span.to)
|
|
70
|
+
return cels; // optimize for long single cel.
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return cels;
|
|
74
|
+
}
|
|
75
|
+
/** @internal */
|
|
76
|
+
export function parseCel(frame) {
|
|
77
|
+
return {
|
|
78
|
+
x: frame.frame.x + (frame.frame.w - frame.sourceSize.w) / 2,
|
|
79
|
+
y: frame.frame.y + (frame.frame.h - frame.sourceSize.h) / 2
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/** @internal */
|
|
83
|
+
export function parseHitboxes(span, slices) {
|
|
84
|
+
let hitbox;
|
|
85
|
+
let hurtbox;
|
|
86
|
+
// https://github.com/aseprite/aseprite/issues/3524
|
|
87
|
+
for (const slice of slices) {
|
|
88
|
+
if (slice.name !== span.name)
|
|
89
|
+
continue;
|
|
90
|
+
if (!slice.keys[0])
|
|
91
|
+
continue;
|
|
92
|
+
for (const k of slice.keys)
|
|
93
|
+
if (!boxEq(k.bounds, slice.keys[0].bounds))
|
|
94
|
+
throw Error(`atlas tag "${span.name}" hitbox bounds varies across frames`);
|
|
95
|
+
const red = slice.color === '#ff0000ff';
|
|
96
|
+
const green = slice.color === '#00ff00ff';
|
|
97
|
+
const blue = slice.color === '#0000ffff'; // default Aseprite slice color.
|
|
98
|
+
if (!red && !green && !blue)
|
|
99
|
+
throw Error(`atlas tag "${span.name}" hitbox color ${slice.color} unsupported`);
|
|
100
|
+
if (hitbox && (red || blue))
|
|
101
|
+
throw Error(`atlas tag "${span.name}" has multiple hitboxes`);
|
|
102
|
+
if (hurtbox && (green || blue))
|
|
103
|
+
throw Error(`atlas tag "${span.name}" has multiple hurtboxes`);
|
|
104
|
+
if (red || blue)
|
|
105
|
+
hitbox = slice.keys[0].bounds;
|
|
106
|
+
if (green || blue)
|
|
107
|
+
hurtbox = slice.keys[0].bounds;
|
|
108
|
+
}
|
|
109
|
+
return { hitbox, hurtbox };
|
|
110
|
+
}
|
|
111
|
+
function parseTag(tag) {
|
|
112
|
+
if (!tag.includes('--'))
|
|
113
|
+
throw Error(`atlas tag "${tag}" not in <filestem>--<animation> format`);
|
|
114
|
+
return tag;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=atlas-json-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atlas-json-parser.js","sourceRoot":"","sources":["../../../tools/atlas-pack/atlas-json-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { exec } from "../utils/exec.js";
|
|
4
|
+
import { globAll } from "../utils/file-util.js";
|
|
5
|
+
import { parseAtlasJSON } from "./atlas-json-parser.js";
|
|
6
|
+
// to-do: separate executable?
|
|
7
|
+
export async function packAtlas(config) {
|
|
8
|
+
const filenames = await globAll(path.join(config.dir, '**.aseprite'));
|
|
9
|
+
if (!filenames.length)
|
|
10
|
+
return;
|
|
11
|
+
const webp = config.image.endsWith('.webp');
|
|
12
|
+
const sheet = webp ? config.image.replace('.webp', '.png') : config.image;
|
|
13
|
+
const json = await exec('aseprite', '--batch', '--color-mode=indexed', '--filename-format={title}--{tag}--{frame}', '--list-slices', '--list-tags', '--merge-duplicates', `--sheet=${sheet}`, '--sheet-pack', '--tagname-format={title}--{tag}', ...filenames);
|
|
14
|
+
if (webp)
|
|
15
|
+
await exec('cwebp', '-exact', '-lossless', '-mt', '-quiet', '-z', '9', sheet, '-o', config.image);
|
|
16
|
+
await fs.writeFile(config.json, JSON.stringify(parseAtlasJSON(JSON.parse(json))));
|
|
17
|
+
try {
|
|
18
|
+
await exec('biome', 'check', '--fix', config.json);
|
|
19
|
+
}
|
|
20
|
+
catch { }
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=atlas-pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atlas-pack.js","sourceRoot":"","sources":["../../../tools/atlas-pack/atlas-pack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAA;AACjC,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAA;AACrC,OAAO,EAAC,OAAO,EAAC,MAAM,uBAAuB,CAAA;AAC7C,OAAO,EAAC,cAAc,EAAC,MAAM,wBAAwB,CAAA;AAErD,8BAA8B;AAC9B,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,MAA6B;IAC3D,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAA;IACrE,IAAI,CAAC,SAAS,CAAC,MAAM;QAAE,OAAM;IAE7B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAA;IACzE,MAAM,IAAI,GAAG,MAAM,IAAI,CACrB,UAAU,EACV,SAAS,EACT,sBAAsB,EACtB,2CAA2C,EAC3C,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,WAAW,KAAK,EAAE,EAClB,cAAc,EACd,iCAAiC,EACjC,GAAG,SAAS,CACb,CAAA;IAED,IAAI,IAAI;QACN,MAAM,IAAI,CACR,OAAO,EACP,QAAQ,EACR,WAAW,EACX,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,EACJ,MAAM,CAAC,KAAK,CACb,CAAA;IAEH,MAAM,EAAE,CAAC,SAAS,CAChB,MAAM,CAAC,IAAI,EACX,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CACjD,CAAA;IAED,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IACpD,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;AACZ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import esbuild from 'esbuild';
|
|
3
|
+
import * as V from "../../src/index.js";
|
|
4
|
+
import { packAtlas } from "../atlas-pack/atlas-pack.js";
|
|
5
|
+
import { HTMLPlugin } from "./html-plugin.js";
|
|
6
|
+
export async function bundle(config, srcFilenames, voidVersion) {
|
|
7
|
+
const opts = {
|
|
8
|
+
banner: config.watch
|
|
9
|
+
? {
|
|
10
|
+
js: "new EventSource('/esbuild').addEventListener('change', () => location.reload());"
|
|
11
|
+
}
|
|
12
|
+
: {},
|
|
13
|
+
bundle: true,
|
|
14
|
+
define: {
|
|
15
|
+
// define on globalThis to avoid ReferenceError in unit tests.
|
|
16
|
+
'globalThis.voidVersion': JSON.stringify(voidVersion)
|
|
17
|
+
},
|
|
18
|
+
entryPoints: [...srcFilenames],
|
|
19
|
+
format: 'esm',
|
|
20
|
+
logLevel: 'info', // print the port and build demarcations.
|
|
21
|
+
metafile: true,
|
|
22
|
+
minify: config.minify,
|
|
23
|
+
outdir: config.out.dir,
|
|
24
|
+
plugins: [HTMLPlugin(config)],
|
|
25
|
+
sourcemap: 'linked',
|
|
26
|
+
target: 'es2024' // https://esbuild.github.io/content-types/#tsconfig-json
|
|
27
|
+
};
|
|
28
|
+
if (config.preloadAtlas)
|
|
29
|
+
await packAtlas(config.preloadAtlas);
|
|
30
|
+
if (config.preloadAtlas && config.watch) {
|
|
31
|
+
fs.watch(config.preloadAtlas.dir, { recursive: true }, (ev, type) => onWatch(config.preloadAtlas, ev, type));
|
|
32
|
+
const ctx = await esbuild.context(opts);
|
|
33
|
+
await Promise.all([
|
|
34
|
+
ctx.watch(),
|
|
35
|
+
ctx.serve({ port: 1234, servedir: config.out.dir })
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const build = await esbuild.build(opts);
|
|
40
|
+
if (config.meta)
|
|
41
|
+
await fs.promises.writeFile(config.meta, JSON.stringify(build.metafile));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const onWatch = V.debounce(async (config, ev, file) => {
|
|
45
|
+
console.log(`asset ${file} ${ev}.`);
|
|
46
|
+
await packAtlas(config);
|
|
47
|
+
}, 500);
|
|
48
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../../tools/bundle/bundle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,KAAK,CAAC,MAAM,oBAAoB,CAAA;AAEvC,OAAO,EAAC,SAAS,EAAC,MAAM,6BAA6B,CAAA;AAErD,OAAO,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,MAAwB,EACxB,YAA+B,EAC/B,WAAkC;IAElC,MAAM,IAAI,GAAyB;QACjC,MAAM,EAAE,MAAM,CAAC,KAAK;YAClB,CAAC,CAAC;gBACE,EAAE,EAAE,kFAAkF;aACvF;YACH,CAAC,CAAC,EAAE;QACN,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE;YACN,8DAA8D;YAC9D,wBAAwB,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;SACtD;QACD,WAAW,EAAE,CAAC,GAAG,YAAY,CAAC;QAC9B,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,MAAM,EAAE,yCAAyC;QAC3D,QAAQ,EAAE,IAAI;QACd,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG;QACtB,OAAO,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC7B,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,QAAQ,CAAC,yDAAyD;KAC3E,CAAA;IAED,IAAI,MAAM,CAAC,YAAY;QAAE,MAAM,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;IAC7D,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QACxC,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,EAAE,CAChE,OAAO,CAAC,MAAM,CAAC,YAAa,EAAE,EAAE,EAAE,IAAI,CAAC,CACxC,CAAA;QACD,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,OAAO,CAAC,GAAG,CAAC;YAChB,GAAG,CAAC,KAAK,EAAE;YACX,GAAG,CAAC,KAAK,CAAC,EAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAC,CAAC;SAClD,CAAC,CAAA;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,MAAM,CAAC,IAAI;YACb,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC5E,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,CAAC,CAAC,QAAQ,CACxB,KAAK,EACH,MAA6B,EAC7B,EAAqB,EACrB,IAAmB,EACnB,EAAE;IACF,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,IAAI,EAAE,GAAG,CAAC,CAAA;IACnC,MAAM,SAAS,CAAC,MAAM,CAAC,CAAA;AACzB,CAAC,EACD,GAAe,CAChB,CAAA"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { minify } from 'html-minifier-next';
|
|
4
|
+
import { exec } from "../utils/exec.js";
|
|
5
|
+
import { parseHTML } from "../utils/html-parser.js";
|
|
6
|
+
export function HTMLPlugin(config) {
|
|
7
|
+
return {
|
|
8
|
+
name: 'HTMLPlugin',
|
|
9
|
+
setup(build) {
|
|
10
|
+
build.onEnd(async (_result) => {
|
|
11
|
+
const doc = await parseHTML(config.entry);
|
|
12
|
+
const scripts = doc.querySelectorAll("script[type='module'][src$='.ts']");
|
|
13
|
+
for (const script of scripts) {
|
|
14
|
+
// to-do: test.
|
|
15
|
+
const filename = path.basename(script.getAttribute('src').replace(/\.ts$/, '.js'));
|
|
16
|
+
if (config.oneFile) {
|
|
17
|
+
script.removeAttribute('src');
|
|
18
|
+
script.textContent = await fs.readFile(path.join(config.out.dir, filename), { encoding: 'utf8' });
|
|
19
|
+
}
|
|
20
|
+
else
|
|
21
|
+
script.src = filename;
|
|
22
|
+
}
|
|
23
|
+
if (config.oneFile) {
|
|
24
|
+
const imgs = doc.querySelectorAll('img[src]');
|
|
25
|
+
for (const img of imgs) {
|
|
26
|
+
const filename = img.getAttribute('src');
|
|
27
|
+
const b64 = await fs.readFile(path.join(config.out.dir, filename), {
|
|
28
|
+
encoding: 'base64'
|
|
29
|
+
});
|
|
30
|
+
const ext = filename.match(/\.([^.]+)$/)?.[1];
|
|
31
|
+
if (!ext)
|
|
32
|
+
throw Error('no asset extension');
|
|
33
|
+
img.src = `data:image/${ext};base64,${b64}`;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const manifestEl = doc.querySelector('link[href][rel="manifest"]');
|
|
37
|
+
if (manifestEl) {
|
|
38
|
+
const manifestFilename = path.resolve(path.dirname(config.entry), manifestEl.getAttribute('href'));
|
|
39
|
+
const manifest = JSON.parse(await fs.readFile(manifestFilename, 'utf8'));
|
|
40
|
+
if (config.version)
|
|
41
|
+
manifest.version = config.version;
|
|
42
|
+
for (const icon of manifest.icons ?? []) {
|
|
43
|
+
if (!icon.src || !icon.type)
|
|
44
|
+
continue;
|
|
45
|
+
const iconFilename = `${path.dirname(manifestFilename)}/${icon.src}`;
|
|
46
|
+
const file = await fs.readFile(iconFilename);
|
|
47
|
+
if (config.oneFile)
|
|
48
|
+
icon.src = `data:${icon.type};base64,${file.toString('base64')}`;
|
|
49
|
+
else
|
|
50
|
+
icon.src = path.relative(config.out.dir, iconFilename);
|
|
51
|
+
}
|
|
52
|
+
if (config.watch)
|
|
53
|
+
manifest.start_url = 'http://localhost:1234';
|
|
54
|
+
if (config.oneFile)
|
|
55
|
+
manifestEl.href = `data:application/json,${encodeURIComponent(JSON.stringify(manifest))}`;
|
|
56
|
+
else
|
|
57
|
+
await fs.writeFile(path.join(config.out.dir, path.basename(manifestFilename)), JSON.stringify(manifest));
|
|
58
|
+
}
|
|
59
|
+
if (config.oneFile) {
|
|
60
|
+
const icons = doc.querySelectorAll('link[href][rel="icon"][type]');
|
|
61
|
+
for (const icon of icons) {
|
|
62
|
+
const filename = path.resolve(config.out.dir, icon.getAttribute('href'));
|
|
63
|
+
const file = await fs.readFile(filename);
|
|
64
|
+
icon.href = `data:${icon.type};base64,${file.toString('base64')}`;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
let html = `<!doctype html>\n${doc.documentElement.outerHTML}`;
|
|
68
|
+
if (config.minify)
|
|
69
|
+
html = await minify(html, {
|
|
70
|
+
caseSensitive: true,
|
|
71
|
+
collapseBooleanAttributes: true,
|
|
72
|
+
html5: true,
|
|
73
|
+
minifyCSS: true,
|
|
74
|
+
removeAttributeQuotes: true,
|
|
75
|
+
removeComments: true,
|
|
76
|
+
removeEmptyAttributes: true
|
|
77
|
+
});
|
|
78
|
+
else
|
|
79
|
+
try {
|
|
80
|
+
html = await exec('biome', 'check', '--fix', `--stdin-file-path=${config.entry}`, { stdin: html });
|
|
81
|
+
}
|
|
82
|
+
catch { }
|
|
83
|
+
// to-do: test.
|
|
84
|
+
const outHTMLFilename = path.join(config.out.dir, config.out.filename);
|
|
85
|
+
await fs.writeFile(outHTMLFilename, html);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=html-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-plugin.js","sourceRoot":"","sources":["../../../tools/bundle/html-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// TypeScript config defaults for each sub-project (src, test, etc).
|
|
2
|
+
{
|
|
3
|
+
"$schema": "https://json.schemastore.org/tsconfig.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
// enable incremental builds.
|
|
6
|
+
"composite": true,
|
|
7
|
+
// enable type-stripping.
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
9
|
+
// only allow type-strippable syntax.
|
|
10
|
+
"erasableSyntaxOnly": true,
|
|
11
|
+
// maximize type checking.
|
|
12
|
+
"allowUnreachableCode": false,
|
|
13
|
+
"allowUnusedLabels": false,
|
|
14
|
+
"exactOptionalPropertyTypes": true,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"noImplicitOverride": true,
|
|
17
|
+
"noUncheckedIndexedAccess": true,
|
|
18
|
+
"noUncheckedSideEffectImports": true,
|
|
19
|
+
"noUnusedLocals": true,
|
|
20
|
+
"resolveJsonModule": true,
|
|
21
|
+
"strict": true,
|
|
22
|
+
// projects add types as needed.
|
|
23
|
+
"lib": ["ES2024", "ESNext.disposable"],
|
|
24
|
+
"types": [],
|
|
25
|
+
"isolatedDeclarations": true, // require explicit types.
|
|
26
|
+
// improve compatibility with compilers that aren't type system aware.
|
|
27
|
+
"isolatedModules": true,
|
|
28
|
+
"esModuleInterop": true, // use ESM.
|
|
29
|
+
// allow JSON type-checking and imports.
|
|
30
|
+
"module": "ESNext",
|
|
31
|
+
"moduleResolution": "Bundler",
|
|
32
|
+
"rewriteRelativeImportExtensions": true, // rewrite .ts imports to .js.
|
|
33
|
+
// all subprojects output to dist/ relative the project root.
|
|
34
|
+
"outDir": "../dist",
|
|
35
|
+
"rootDir": "..",
|
|
36
|
+
// assume library types are checked and compatible.
|
|
37
|
+
"skipLibCheck": true,
|
|
38
|
+
"skipDefaultLibCheck": true,
|
|
39
|
+
"sourceMap": true,
|
|
40
|
+
"target": "ES2024",
|
|
41
|
+
// don't transform type-only imports.
|
|
42
|
+
"verbatimModuleSyntax": true
|
|
43
|
+
},
|
|
44
|
+
// include all sources and JSON.
|
|
45
|
+
"include": ["${configDir}/", "${configDir}/**/*.json"],
|
|
46
|
+
// exclude colocated tests and test utils.
|
|
47
|
+
"exclude": ["${configDir}/**/*.test.*", "${configDir}/**/test/"]
|
|
48
|
+
}
|