@dryanovski/gamefoo 0.0.1 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/core/animate.d.ts +129 -0
  2. package/dist/core/animate.d.ts.map +1 -0
  3. package/dist/core/asset.d.ts +59 -0
  4. package/dist/core/asset.d.ts.map +1 -0
  5. package/dist/core/behaviour.d.ts +118 -0
  6. package/dist/core/behaviour.d.ts.map +1 -1
  7. package/dist/core/behaviours/collidable.d.ts +203 -4
  8. package/dist/core/behaviours/collidable.d.ts.map +1 -1
  9. package/dist/core/behaviours/control.d.ts +51 -3
  10. package/dist/core/behaviours/control.d.ts.map +1 -1
  11. package/dist/core/behaviours/healtkit.d.ts +120 -3
  12. package/dist/core/behaviours/healtkit.d.ts.map +1 -1
  13. package/dist/core/behaviours/sprite_render.d.ts +141 -0
  14. package/dist/core/behaviours/sprite_render.d.ts.map +1 -0
  15. package/dist/core/camera.d.ts +101 -0
  16. package/dist/core/camera.d.ts.map +1 -1
  17. package/dist/core/engine.d.ts +377 -15
  18. package/dist/core/engine.d.ts.map +1 -1
  19. package/dist/core/fonts/font_bitmap.d.ts +156 -0
  20. package/dist/core/fonts/font_bitmap.d.ts.map +1 -0
  21. package/dist/core/fonts/font_bitmap_prebuild.d.ts +102 -0
  22. package/dist/core/fonts/font_bitmap_prebuild.d.ts.map +1 -0
  23. package/dist/core/fonts/internal/font_3x5.d.ts +76 -0
  24. package/dist/core/fonts/internal/font_3x5.d.ts.map +1 -0
  25. package/dist/core/fonts/internal/font_4x6.d.ts +76 -0
  26. package/dist/core/fonts/internal/font_4x6.d.ts.map +1 -0
  27. package/dist/core/fonts/internal/font_5x5.d.ts +79 -0
  28. package/dist/core/fonts/internal/font_5x5.d.ts.map +1 -0
  29. package/dist/core/fonts/internal/font_6x8.d.ts +76 -0
  30. package/dist/core/fonts/internal/font_6x8.d.ts.map +1 -0
  31. package/dist/core/fonts/internal/font_8x13.d.ts +76 -0
  32. package/dist/core/fonts/internal/font_8x13.d.ts.map +1 -0
  33. package/dist/core/fonts/internal/font_8x8.d.ts +76 -0
  34. package/dist/core/fonts/internal/font_8x8.d.ts.map +1 -0
  35. package/dist/core/game_object_register.d.ts +101 -1
  36. package/dist/core/game_object_register.d.ts.map +1 -1
  37. package/dist/core/input.d.ts +131 -0
  38. package/dist/core/input.d.ts.map +1 -1
  39. package/dist/core/sprite.d.ts +232 -0
  40. package/dist/core/sprite.d.ts.map +1 -0
  41. package/dist/core/utils/perlin_noise.d.ts +136 -0
  42. package/dist/core/utils/perlin_noise.d.ts.map +1 -0
  43. package/dist/core/world.d.ts +147 -0
  44. package/dist/core/world.d.ts.map +1 -1
  45. package/dist/debug/monitor.d.ts +12 -0
  46. package/dist/debug/monitor.d.ts.map +1 -0
  47. package/dist/decorators/index.d.ts +2 -0
  48. package/dist/decorators/index.d.ts.map +1 -0
  49. package/dist/decorators/log.d.ts +33 -0
  50. package/dist/decorators/log.d.ts.map +1 -0
  51. package/dist/entities/dynamic_entity.d.ts +82 -0
  52. package/dist/entities/dynamic_entity.d.ts.map +1 -1
  53. package/dist/entities/entity.d.ts +216 -11
  54. package/dist/entities/entity.d.ts.map +1 -1
  55. package/dist/entities/player.d.ts +76 -0
  56. package/dist/entities/player.d.ts.map +1 -1
  57. package/dist/entities/text.d.ts +52 -0
  58. package/dist/entities/text.d.ts.map +1 -0
  59. package/dist/index.d.ts +29 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +23 -604
  62. package/dist/index.js.map +3 -15
  63. package/dist/subsystems/camera_system.d.ts +25 -0
  64. package/dist/subsystems/camera_system.d.ts.map +1 -0
  65. package/dist/subsystems/collision_system.d.ts +16 -0
  66. package/dist/subsystems/collision_system.d.ts.map +1 -0
  67. package/dist/subsystems/monitor_system.d.ts +17 -0
  68. package/dist/subsystems/monitor_system.d.ts.map +1 -0
  69. package/dist/subsystems/object_system.d.ts +18 -0
  70. package/dist/subsystems/object_system.d.ts.map +1 -0
  71. package/dist/subsystems/types.d.ts +40 -0
  72. package/dist/subsystems/types.d.ts.map +1 -0
  73. package/dist/types.d.ts +140 -0
  74. package/dist/types.d.ts.map +1 -1
  75. package/package.json +25 -11
package/dist/index.js.map CHANGED
@@ -1,21 +1,9 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../core/behaviour.ts", "../core/behaviours/collidable.ts", "../core/behaviours/control.ts", "../core/behaviours/healtkit.ts", "../core/camera.ts", "../core/game_object_register.ts", "../core/world.ts", "../core/engine.ts", "../core/input.ts", "../entities/entity.ts", "../entities/dynamic_entity.ts", "../entities/player.ts"],
3
+ "sources": [],
4
4
  "sourcesContent": [
5
- "import type Entity from \"../entities/entity\";\n\nexport abstract class Behaviour<T extends Entity = Entity> {\n protected owner: T;\n\n abstract readonly type: string;\n\n public priority: number = 1;\n\n public enabled: boolean = true;\n\n get key(): string {\n return this.type.toLowerCase();\n }\n\n constructor(owner: T) {\n this.owner = owner;\n }\n\n abstract update(deltaTime: number): void;\n\n render?(ctx: CanvasRenderingContext2D): void;\n onAttach?(): void;\n onDetach?(): void;\n}\n",
6
- "import type DynamicEntity from \"../../entities/dynamic_entity\";\nimport type Entity from \"../../entities/entity\";\nimport type { ColliderShape, CollisionInfo, WorldBounds } from \"../../types\";\nimport { Behaviour } from \"../behaviour\";\nimport type World from \"../world\";\n\ntype CollidableOptions = {\n shape: ColliderShape;\n layer?: number;\n tags?: Set<string>;\n collidesWith?: Set<string>;\n solid?: boolean;\n fixed?: boolean;\n onCollision?: (info: CollisionInfo) => void;\n};\n\nexport class Collidable extends Behaviour<DynamicEntity> {\n readonly type = \"collidable\";\n\n public shape: ColliderShape;\n\n public layer: number = 0;\n\n public tags: Set<string> = new Set();\n\n public collidesWith: Set<string> = new Set();\n\n public solid: boolean = false;\n\n public fixed: boolean = false;\n\n public onCollision: (info: CollisionInfo) => void;\n\n private world: World;\n\n constructor(owner: DynamicEntity, world: World, options: CollidableOptions) {\n super(owner);\n\n this.world = world;\n\n const size = owner.getSize();\n\n this.shape = options.shape;\n this.shape = options.shape ?? {\n type: \"aabb\",\n width: size.width,\n height: size.height,\n };\n this.layer = options.layer ?? 0;\n this.tags = options.tags ?? new Set();\n this.solid = options.solid ?? false;\n this.fixed = options.fixed ?? false;\n this.collidesWith = options.collidesWith ?? new Set();\n this.onCollision = options.onCollision || (() => {});\n }\n\n update(_deltaTime: number): void {}\n\n override onAttach(): void {\n this.world.register(this);\n }\n\n override onDetach(): void {\n this.world.unregister(this);\n }\n\n getOwner(): Entity {\n return this.owner;\n }\n\n getWorldBounds(): WorldBounds {\n const pos = this.owner.getPosition();\n const offset = \"offset\" in this.shape && this.shape.offset ? this.shape.offset : { x: 0, y: 0 };\n\n if (this.shape.type === \"aabb\") {\n return {\n x: pos.x + offset.x,\n y: pos.y + offset.y,\n width: this.shape.width,\n height: this.shape.height,\n };\n }\n\n const r = this.shape.radius;\n return {\n x: pos.x + offset.x - r,\n y: pos.y + offset.y - r,\n width: r * 2,\n height: r * 2,\n };\n }\n}\n",
7
- "import type DynamicEntity from \"../../entities/dynamic_entity\";\nimport { Behaviour } from \"../behaviour\";\nimport type Input from \"../input\";\n\nexport class Control extends Behaviour<DynamicEntity> {\n readonly type = \"control\";\n\n private input: Input;\n\n private speed: number = 500; // pixels per second\n\n constructor(owner: DynamicEntity, input: Input) {\n super(owner);\n this.input = input;\n }\n\n update(deltaTime: number): void {\n let dx = 0;\n let dy = 0;\n\n if (this.input.isKeyDown(\"a\") || this.input.isKeyDown(\"arrowleft\")) dx -= 1;\n if (this.input.isKeyDown(\"d\") || this.input.isKeyDown(\"arrowright\")) dx += 1;\n if (this.input.isKeyDown(\"w\") || this.input.isKeyDown(\"arrowup\")) dy -= 1;\n if (this.input.isKeyDown(\"s\") || this.input.isKeyDown(\"arrowdown\")) dy += 1;\n\n // Normalize diagonal movement\n const len = Math.sqrt(dx * dx + dy * dy);\n if (len > 0) {\n this.owner.x += (dx / len) * this.speed * deltaTime;\n this.owner.y += (dy / len) * this.speed * deltaTime;\n }\n }\n}\n",
8
- "import type DynamicEntity from \"../../entities/dynamic_entity\";\nimport { Behaviour } from \"../behaviour\";\n\nexport class HealthKit extends Behaviour<DynamicEntity> {\n readonly type = \"healthkit\";\n\n private health: number;\n private maxHP: number;\n\n constructor(owner: DynamicEntity, health: number, maxHP?: number) {\n super(owner);\n this.health = health;\n this.maxHP = maxHP || health;\n }\n\n update(_deltaTime: number): void {}\n\n takeDamage(amount: number): void {\n this.health = Math.max(0, this.health - amount);\n }\n\n heal(amount: number): void {\n this.health = Math.min(this.maxHP, this.health + amount);\n }\n\n getHealth(): number {\n return this.health;\n }\n\n getMaxHealth(): number {\n return this.maxHP;\n }\n\n setMaxHealth(value: number): void {\n this.maxHP = value;\n if (this.health > this.maxHP) {\n this.health = this.maxHP;\n }\n }\n\n isDead(): boolean {\n return this.health <= 0;\n }\n\n getHealthPercent(): number {\n return this.maxHP > 0 ? this.health / this.maxHP : 0;\n }\n}\n",
9
- "import type { Vector2 } from \"../types\";\n\nexport default class Camera {\n private x: number = 0;\n private y: number = 0;\n private width: number;\n private height: number;\n\n constructor(width: number, height: number) {\n this.width = width;\n this.height = height;\n }\n\n follow(target: Vector2): void {\n this.x = target.x;\n this.y = target.y;\n }\n\n moveTo(target: Vector2): void {\n this.x = target.x;\n this.y = target.y;\n }\n\n getPosition(): Vector2 {\n return { x: this.x, y: this.y };\n }\n\n getViewRect(): { x: number; y: number; width: number; height: number } {\n return {\n x: this.x - this.width / 2,\n y: this.y - this.height / 2,\n width: this.width,\n height: this.height,\n };\n }\n\n resize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n }\n}\n",
10
- "import type { GameObject } from \"../types\";\n\nexport default class GameObjectRegister {\n private objects: Map<string, GameObject> = new Map();\n\n register(object: GameObject) {\n this.objects.set(object.id, object);\n }\n\n get(id: string): GameObject | undefined {\n return this.objects.get(id);\n }\n\n has(id: string): boolean {\n return this.objects.has(id);\n }\n\n getAll(_filter: () => true): GameObject[] {\n return Array.from(this.objects.values()).filter(_filter);\n }\n\n updateAll(deltaTime: number): void {\n this.getAll(() => true).forEach((obj) => {\n obj.update(deltaTime);\n });\n }\n\n renderAll(ctx: CanvasRenderingContext2D): void {\n this.getAll(() => true).forEach((obj) => {\n obj.render(ctx);\n });\n }\n}\n",
11
- "import type { WorldBounds } from \"../types\";\nimport type { Collidable } from \"./behaviours/collidable\";\n\nexport default class World {\n private colliders: Set<Collidable> = new Set();\n\n register(collider: Collidable): void {\n this.colliders.add(collider);\n }\n\n unregister(collider: Collidable): void {\n this.colliders.delete(collider);\n }\n\n detect(): void {\n const list = Array.from(this.colliders);\n const len = list.length;\n\n for (let i = 0; i < len; i++) {\n const obj = list[i];\n if (!obj?.enabled) continue;\n\n for (let j = i + 1; j < len; j++) {\n const other = list[j];\n if (!other?.enabled) continue;\n\n if (obj.layer !== other.layer) continue;\n\n const objWantOther = this.tagsOverlap(obj.collidesWith, other.tags);\n const otherWantObj = this.tagsOverlap(other.collidesWith, obj.tags);\n\n const boundsObj = obj.getWorldBounds();\n const boundsOther = other.getWorldBounds();\n\n if (!this.intersects(obj, boundsObj, other, boundsOther)) continue;\n\n if (obj.solid && other.solid) {\n this.resolveOverlap(obj, boundsObj, other, boundsOther);\n }\n\n if (objWantOther && obj.onCollision) {\n obj.onCollision({\n self: obj.getOwner(),\n other: other.getOwner(),\n selfTags: obj.tags,\n otherTags: other.tags,\n });\n }\n\n if (otherWantObj && other.onCollision) {\n other.onCollision({\n self: other.getOwner(),\n other: obj.getOwner(),\n selfTags: other.tags,\n otherTags: obj.tags,\n });\n }\n }\n }\n }\n\n private tagsOverlap(wants: Set<string>, has: Set<string>): boolean {\n for (const tag of wants) {\n if (has.has(tag)) return true;\n }\n return false;\n }\n\n private intersects(\n a: Collidable,\n boundsA: WorldBounds,\n b: Collidable,\n boundsB: WorldBounds,\n ): boolean {\n const shapeA = a.shape;\n const shapeB = b.shape;\n\n if (shapeA.type === \"aabb\" && shapeB.type === \"aabb\") {\n return this.aabbVSAabb(boundsA, boundsB);\n }\n\n if (shapeA.type === \"circle\" && shapeB.type === \"circle\") {\n return this.circleVSCircle(a, boundsA, b, boundsB);\n }\n\n const [circle, circleBounds, rect] =\n shapeA.type === \"circle\" ? [a, boundsA, boundsB] : [b, boundsB, boundsA];\n\n return this.circleVSAAabb(circle, circleBounds, rect);\n }\n private aabbVSAabb(a: WorldBounds, b: WorldBounds): boolean {\n return (\n a.x < b.x + b.width && a.x + a.width > b.x && a.y < b.y + b.height && a.y + a.height > b.y\n );\n }\n\n private circleVSCircle(\n a: Collidable,\n boundsA: WorldBounds,\n b: Collidable,\n boundsB: WorldBounds,\n ): boolean {\n if (a.shape.type !== \"circle\" || b.shape.type !== \"circle\") return false;\n\n const cx1 = boundsA.x + a.shape.radius;\n const cy1 = boundsA.y + a.shape.radius;\n const cx2 = boundsB.x + b.shape.radius;\n const cy2 = boundsB.y + b.shape.radius;\n\n const dx = cx2 - cx1;\n const dy = cy2 - cy1;\n const distSq = dx * dx + dy * dy;\n const radSum = a.shape.radius + b.shape.radius;\n\n return distSq <= radSum * radSum;\n }\n\n private circleVSAAabb(circle: Collidable, circleBounds: WorldBounds, rect: WorldBounds): boolean {\n if (circle.shape.type !== \"circle\") return false;\n\n const cx = circleBounds.x + circle.shape.radius;\n const cy = circleBounds.y + circle.shape.radius;\n\n const closestX = Math.max(rect.x, Math.min(cx, rect.x + rect.width));\n const closestY = Math.max(rect.y, Math.min(cy, rect.y + rect.height));\n\n const dx = cx - closestX;\n const dy = cy - closestY;\n\n return dx * dx + dy * dy <= circle.shape.radius * circle.shape.radius;\n }\n\n private resolveOverlap(\n a: Collidable,\n boundsA: WorldBounds,\n b: Collidable,\n boundsB: WorldBounds,\n ): void {\n const overlapX = Math.min(\n boundsA.x + boundsA.width - boundsB.x,\n boundsB.x + boundsB.width - boundsA.x,\n );\n const overlapY = Math.min(\n boundsA.y + boundsA.height - boundsB.y,\n boundsB.y + boundsB.height - boundsA.y,\n );\n\n let pushX = 0;\n let pushY = 0;\n\n if (overlapX < overlapY) {\n pushX = boundsA.x < boundsB.x ? -overlapX : overlapX;\n } else {\n pushY = boundsA.y < boundsB.y ? -overlapY : overlapY;\n }\n\n const ownerA = a.getOwner();\n const ownerB = b.getOwner();\n\n if (a.fixed && b.fixed) {\n return;\n }\n\n if (a.fixed) {\n ownerB.x -= pushX;\n ownerB.y -= pushY;\n } else if (b.fixed) {\n ownerA.x += pushX;\n ownerA.y += pushY;\n } else {\n ownerA.x += pushX / 2;\n ownerA.y += pushY / 2;\n ownerB.x -= pushX / 2;\n ownerB.y -= pushY / 2;\n }\n }\n}\n",
12
- "import type Player from \"../entities/player\";\nimport type { GameObject } from \"../types\";\nimport Camera from \"./camera\";\nimport GameObjectRegister from \"./game_object_register\";\nimport World from \"./world\";\n\ninterface EngineConfig {\n backgroundColor?: string;\n}\n\n/**\n * Game Engine - the main class that manages the game loop, rendering, and overall game state.\n */\nexport default class Engine {\n private canvas: HTMLCanvasElement;\n private ctx: CanvasRenderingContext2D;\n\n private lastTime: number = 0;\n\n private width: number;\n private height: number;\n\n private _initialized: boolean = false;\n private running: boolean = false;\n\n private cnf: EngineConfig = {\n backgroundColor: \"#000000\",\n };\n\n private _player?: Player;\n\n private engine: {\n camera: Camera | null;\n objects: GameObjectRegister; // Placeholder for game objects, can be expanded later\n collisions: World;\n };\n\n constructor(canvasId: string, width: number, height: number, config: EngineConfig) {\n this.canvas = document.getElementById(canvasId) as HTMLCanvasElement;\n this.height = height;\n this.width = width;\n this.canvas.width = width;\n this.canvas.height = height;\n const context = this.canvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"Failed to get 2D context\");\n }\n this.ctx = context;\n\n this.cnf = { ...this.cnf, ...config };\n\n this.engine = {\n /**\n * Maybe later will find a beter way to initialize this\n */\n camera: new Camera(this.width, this.height),\n\n /**\n * This holds all the game objects\n */\n objects: new GameObjectRegister(),\n\n collisions: new World(),\n };\n }\n\n set player(player: Player) {\n this._player = player;\n }\n\n get player(): Player | undefined {\n return this._player;\n }\n\n get collisions(): World {\n return this.engine.collisions;\n }\n\n public attachObjects(objects: GameObject) {\n this.engine.objects.register(objects);\n }\n\n handleResize() {\n if (!this.canvas) return;\n\n const container = this.canvas.parentElement;\n if (!container) return;\n\n const containerWidth = container.clientWidth;\n const containerHeight = container.clientHeight;\n\n const scaleX = containerWidth / this.width;\n const scaleY = containerHeight / this.height;\n const scale = Math.min(scaleX, scaleY);\n const offsetX = (containerWidth - this.width * scale) / 2;\n const offsetY = (containerHeight - this.height * scale) / 2;\n\n this.canvas.style.transform = `translate(${offsetX}px, ${offsetY}px) scale(${scale})`;\n }\n\n resize(width: number, height: number): void {\n this.canvas.width = width;\n this.canvas.height = height;\n }\n\n private loop(timestamp: number) {\n if (!this.running) {\n return;\n }\n\n if (this.lastTime === 0) {\n this.lastTime = timestamp;\n }\n\n const deltaTime = (timestamp - this.lastTime) / 1000;\n this.lastTime = timestamp;\n\n this.update(deltaTime);\n this.render();\n requestAnimationFrame((timestamp) => this.loop(timestamp));\n }\n\n /**\n * Public - cause I'm old school\n */\n\n public async setup(setupFn: () => void) {\n if (this._initialized) {\n console.warn(\"Engine is already initialized.\");\n return;\n }\n\n if (typeof setupFn !== \"function\") {\n throw new Error(\"Setup function must be provided and must be a function.\");\n }\n\n this.lastTime = 0;\n setupFn();\n this._initialized = true;\n this.running = true;\n requestAnimationFrame((timestamp) => this.loop(timestamp));\n }\n\n public update(deltaTime: number) {\n if (this.player) {\n this.player.update(deltaTime);\n }\n\n if (this.engine.objects) {\n this.engine.objects.updateAll(deltaTime);\n }\n\n this.engine.collisions.detect();\n\n /**\n * There is oportunity to optimize this with much better follow mechanic\n * but I'm to lazy today so won't do it\n */\n if (this.engine.camera && this.player) {\n this.engine.camera.follow(this.player.getPosition());\n }\n }\n\n public render() {\n this.ctx.clearRect(0, 0, this.width, this.height);\n this.ctx.fillStyle = this.cnf.backgroundColor || \"#000000\";\n this.ctx.fillRect(0, 0, this.width, this.height);\n\n if (this.player) {\n this.player.render(this.ctx);\n }\n\n if (this.engine.objects) {\n this.engine.objects.renderAll(this.ctx);\n }\n }\n\n public pause() {\n this.running = false;\n }\n\n public clear() {\n this.running = false;\n this.ctx.clearRect(0, 0, this.width, this.height);\n }\n\n public destroy() {\n // Clean up resources, event listeners, etc. if needed.\n }\n}\n",
13
- "export default class Input {\n private keys: Set<string> = new Set();\n private mouseButtons: Set<number> = new Set();\n private mousePosition: { x: number; y: number } = { x: 0, y: 0 };\n\n constructor() {\n window.addEventListener(\"keydown\", (e) => {\n this.keys.add(e.key.toLowerCase());\n });\n\n window.addEventListener(\"keyup\", (e) => {\n this.keys.delete(e.key.toLowerCase());\n });\n\n // Mouse events\n window.addEventListener(\"mousedown\", (e) => {\n this.mouseButtons.add(e.button);\n });\n\n window.addEventListener(\"mouseup\", (e) => {\n this.mouseButtons.delete(e.button);\n });\n\n window.addEventListener(\"mousemove\", (e) => {\n this.mousePosition = { x: e.clientX, y: e.clientY };\n });\n }\n\n isKeyDown(key: string): boolean {\n return this.keys.has(key.toLowerCase());\n }\n\n getPressedKeys(): Set<string> {\n return new Set(this.keys);\n }\n\n isMouseButtonDown(button: number): boolean {\n return this.mouseButtons.has(button);\n }\n\n getMousePosition(): { x: number; y: number } {\n return { ...this.mousePosition };\n }\n\n reset(): void {\n this.keys.clear();\n this.mouseButtons.clear();\n }\n}\n",
14
- "import type { Behaviour } from \"../core/behaviour\";\nimport type { Vector2 } from \"../types\";\n\nexport default abstract class Entity {\n public id: string = \"\";\n protected position: Vector2 = { x: 0, y: 0 };\n protected size = { width: 0, height: 0 };\n\n private behaviorMap: Map<string, Behaviour> = new Map();\n private _sortedBehaviors: Behaviour[] | null = null;\n\n get x(): number {\n return this.position.x;\n }\n\n set x(value: number) {\n this.position.x = value;\n }\n\n get y(): number {\n return this.position.y;\n }\n\n set y(value: number) {\n this.position.y = value;\n }\n\n constructor(id: string, x: number, y: number, width: number, height: number) {\n this.id = id;\n this.position = { x, y };\n this.size = { width, height };\n }\n\n abstract update(deltaTime: number): void;\n abstract render(ctx: CanvasRenderingContext2D): void;\n\n getPosition(): Vector2 {\n return { ...this.position };\n }\n\n getSize(): { width: number; height: number } {\n return { ...this.size };\n }\n\n getBehaviour<T extends Behaviour>(key: string): T | undefined {\n return this.behaviorMap.get(key.toLowerCase()) as T | undefined;\n }\n\n getBehavioursByType<T extends Behaviour>(type: new (...args: any[]) => T): T[] {\n return this.behaviors.filter((b) => b instanceof type) as T[];\n }\n\n hasBehaviour(key: string): boolean {\n return this.behaviorMap.has(key.toLowerCase());\n }\n\n attachBehaviour<T extends Behaviour>(behavior: T): T {\n this.behaviorMap.set(behavior.key, behavior);\n this._sortedBehaviors = null; // Invalidate sorted cache\n\n if (behavior.onAttach) {\n behavior.onAttach();\n }\n return behavior;\n }\n\n detachBehaviour(key: string): void {\n const behavior = this.behaviorMap.get(key.toLowerCase());\n if (!behavior) return;\n\n if (behavior.onDetach) {\n behavior.onDetach();\n }\n this.behaviorMap.delete(key.toLowerCase());\n this._sortedBehaviors = null; // Invalidate sorted cache\n }\n\n private get behaviors(): Behaviour[] {\n if (!this._sortedBehaviors) {\n this._sortedBehaviors = Array.from(this.behaviorMap.values()).sort(\n (a, b) => a.priority - b.priority,\n );\n }\n return this._sortedBehaviors;\n }\n\n protected updateBehaviours(deltaTime: number): void {\n for (const behavior of this.behaviors) {\n if (behavior.enabled) {\n behavior.update(deltaTime);\n }\n }\n }\n\n protected renderBehaviours(ctx: CanvasRenderingContext2D): void {\n for (const behavior of this.behaviors) {\n if (behavior.enabled && behavior.render) {\n behavior.render(ctx);\n }\n }\n }\n}\n",
15
- "import type { Vector2 } from \"../types\";\nimport Entity from \"./entity\";\n\nexport default abstract class DynamicEntity extends Entity {\n protected velocity: Vector2 = { x: 0, y: 0 };\n protected speed: number = 0;\n\n setVelocity(velocity: Vector2): void {\n this.velocity = velocity;\n }\n\n getVelocity(): Vector2 {\n return { ...this.velocity };\n }\n\n setSpeed(speed: number): void {\n this.speed = speed;\n }\n\n getSpeed(): number {\n return this.speed;\n }\n}\n",
16
- "import type { Control } from \"../core/behaviours/control\";\nimport type { HealthKit } from \"../core/behaviours/healtkit\";\nimport DynamicEntity from \"./dynamic_entity\";\n\nexport default class Player extends DynamicEntity {\n get control(): Control | undefined {\n return this.getBehaviour<Control>(\"control\");\n }\n\n get healthkit(): HealthKit | undefined {\n return this.getBehaviour<HealthKit>(\"healthkit\");\n }\n\n update(deltaTime: number): void {\n this.updateBehaviours(deltaTime);\n }\n\n render(ctx: CanvasRenderingContext2D): void {\n ctx.fillStyle = \"blue\";\n ctx.fillRect(this.x, this.y, this.size.width, this.size.height);\n this.renderBehaviours(ctx);\n }\n}\n"
17
5
  ],
18
- "mappings": "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",
19
- "debugId": "AC6FB9916B04E31F64756E2164756E21",
6
+ "mappings": "",
7
+ "debugId": "B36FB65262DD014964756E2164756E21",
20
8
  "names": []
21
9
  }
@@ -0,0 +1,25 @@
1
+ import Camera from "@/core/camera";
2
+ import type { Vector2 } from "@/types";
3
+ import type { SubSystem } from "./types";
4
+ /**
5
+ * CameraSystem is responsible for managing the camera's position and view.
6
+ * It can follow a target (like a player) and adjust the view accordingly.
7
+ *
8
+ * @since 0.2.0
9
+ *
10
+ * @category SubSystems
11
+ */
12
+ export declare class CameraSystem implements SubSystem {
13
+ /**
14
+ * The unique identifier for this subsystem.
15
+ */
16
+ id: string;
17
+ order: number;
18
+ camera: Camera;
19
+ private target;
20
+ constructor(width: number, height: number, target: () => Vector2 | null);
21
+ update(): void;
22
+ preRender(ctx: CanvasRenderingContext2D): void;
23
+ postRender(ctx: CanvasRenderingContext2D): void;
24
+ }
25
+ //# sourceMappingURL=camera_system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"camera_system.d.ts","sourceRoot":"","sources":["../../src/subsystems/camera_system.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AACnC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;GAOG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C;;OAEG;IACH,EAAE,SAAY;IACd,KAAK,SAAM;IAEX,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,CAAC,MAAM,CAAoC;gBAEtC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,GAAG,IAAI;IAQvE,MAAM;IAWN,SAAS,CAAC,GAAG,EAAE,wBAAwB;IAMvC,UAAU,CAAC,GAAG,EAAE,wBAAwB;CAGzC"}
@@ -0,0 +1,16 @@
1
+ import type { SubSystem } from "./types";
2
+ /**
3
+ * CollisionSystem is responsible for detecting collisions between game objects.
4
+ * It uses the World class to manage and detect collisions based on registered collidable objects.
5
+ *
6
+ * @since 0.2.0
7
+ *
8
+ * @category SubSystems
9
+ */
10
+ export declare class CollisionSystem implements SubSystem {
11
+ id: string;
12
+ order: number;
13
+ private world;
14
+ update(): void;
15
+ }
16
+ //# sourceMappingURL=collision_system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"collision_system.d.ts","sourceRoot":"","sources":["../../src/subsystems/collision_system.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;GAOG;AACH,qBAAa,eAAgB,YAAW,SAAS;IAC/C,EAAE,SAAe;IACjB,KAAK,SAAM;IAEX,OAAO,CAAC,KAAK,CAAe;IAE5B,MAAM;CAGP"}
@@ -0,0 +1,17 @@
1
+ import type { SubSystem } from "./types";
2
+ /**
3
+ * MonitorSystem is responsible for displaying debug information on the screen.
4
+ * It uses the Monitor class to track and render various performance metrics,
5
+ *
6
+ * @since 0.2.0
7
+ *
8
+ * @category SubSystems
9
+ */
10
+ export declare class MonitorSystem implements SubSystem {
11
+ id: string;
12
+ order: number;
13
+ private monitor;
14
+ update(deltaTime: number): void;
15
+ render(ctx: CanvasRenderingContext2D): void;
16
+ }
17
+ //# sourceMappingURL=monitor_system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monitor_system.d.ts","sourceRoot":"","sources":["../../src/subsystems/monitor_system.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;;GAOG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C,EAAE,SAAa;IAEf,KAAK,SAAO;IAEZ,OAAO,CAAC,OAAO,CAAiB;IAEhC,MAAM,CAAC,SAAS,EAAE,MAAM;IAIxB,MAAM,CAAC,GAAG,EAAE,wBAAwB;CAGrC"}
@@ -0,0 +1,18 @@
1
+ import type { GameObject } from "@/types";
2
+ import type { SubSystem } from "./types";
3
+ /**
4
+ * ObjectSystem is responsible for managing all non-player game objects within the engine.
5
+ * It maintains a central registry of game objects and delegates per-frame update and render calls to them.
6
+ *
7
+ * @since 0.2.0
8
+ * @category SubSystems
9
+ */
10
+ export declare class ObjectSystem implements SubSystem {
11
+ id: string;
12
+ order: number;
13
+ private objects;
14
+ constructor(objects?: GameObject[]);
15
+ update(deltaTime: number): void;
16
+ render(ctx: CanvasRenderingContext2D): void;
17
+ }
18
+ //# sourceMappingURL=object_system.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"object_system.d.ts","sourceRoot":"","sources":["../../src/subsystems/object_system.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,EAAE,SAAa;IAEf,KAAK,SAAM;IAEX,OAAO,CAAC,OAAO,CAAgD;gBAEnD,OAAO,GAAE,UAAU,EAAO;IAMtC,MAAM,CAAC,SAAS,EAAE,MAAM;IAOxB,MAAM,CAAC,GAAG,EAAE,wBAAwB;CAKrC"}
@@ -0,0 +1,40 @@
1
+ import type Engine from "@/core/engine";
2
+ /**
3
+ * SubSystem is a modular component of the game engine that can be added or removed as needed.
4
+ * It provides hooks for initialization, updating, rendering, and destruction.
5
+ * Each subsystem can have its own logic and state, and can interact with the engine and other subsystems.
6
+ *
7
+ * @since 0.2.0
8
+ *
9
+ * @category SubSystems
10
+ */
11
+ export interface SubSystem {
12
+ /**
13
+ * A unique identifier for the subsystem, used for registration and management within
14
+ * the engine.
15
+ */
16
+ id: string;
17
+ /**
18
+ * Determines the order in which subsystems are updated and rendered. Subsystems
19
+ * with lower order values are processed first.
20
+ */
21
+ enabled?: boolean;
22
+ /**
23
+ * Determines the order in which subsystems are updated and rendered. Subsystems with
24
+ * lower order values are processed first.
25
+ */
26
+ order?: number;
27
+ /**
28
+ * Called when the subsystem is added to the engine. Use this method to perform any
29
+ * necessary setup or initialization.
30
+ */
31
+ init?(engine: Engine): void;
32
+ preUpdate?(deltaTime: number): void;
33
+ update?(deltaTime: number): void;
34
+ postUpdate?(deltaTime: number): void;
35
+ preRender?(ctx: CanvasRenderingContext2D): void;
36
+ render?(ctx: CanvasRenderingContext2D): void;
37
+ postRender?(ctx: CanvasRenderingContext2D): void;
38
+ destroy?(): void;
39
+ }
40
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/subsystems/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC;;;;;;;;GAQG;AACH,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5B,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,MAAM,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,CAAC,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAErC,SAAS,CAAC,CAAC,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAChD,MAAM,CAAC,CAAC,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,CAAC,GAAG,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAEjD,OAAO,CAAC,IAAI,IAAI,CAAC;CAClB"}
package/dist/types.d.ts CHANGED
@@ -1,30 +1,170 @@
1
+ /**
2
+ * Shared type definitions used throughout the GameFoo engine.
3
+ *
4
+ * This module contains the foundational interfaces and type aliases that
5
+ * form the contract between the engine core, entities, and behaviours.
6
+ *
7
+ * @category Types
8
+ * @module types
9
+ * @since 0.1.0
10
+ */
1
11
  import type DynamicEntity from "./entities/dynamic_entity";
2
12
  import type Entity from "./entities/entity";
13
+ /**
14
+ * A two-dimensional vector representing a position, direction, or offset.
15
+ *
16
+ * Used pervasively across the engine for entity positions, velocities,
17
+ * camera coordinates, and collider offsets.
18
+ *
19
+ * @category Types
20
+ * @since 0.1.0
21
+ *
22
+ * @example Basic position
23
+ * ```ts
24
+ * const position: Vector2 = { x: 100, y: 200 };
25
+ * ```
26
+ *
27
+ * @example Direction vector
28
+ * ```ts
29
+ * const direction: Vector2 = { x: Math.cos(angle), y: Math.sin(angle) };
30
+ * ```
31
+ */
3
32
  export interface Vector2 {
33
+ /** Horizontal component (increases rightward). */
4
34
  x: number;
35
+ /** Vertical component (increases downward in canvas coordinates). */
5
36
  y: number;
6
37
  }
38
+ /**
39
+ * An object representin 2D demensions of anything
40
+ *
41
+ * @category Types
42
+ * @since 0.2.0
43
+ *
44
+ * @example Basic set
45
+ * ```ts
46
+ * const Size: Demension = { width: 32, height: 32 };
47
+ * ```
48
+ */
49
+ export interface Demension {
50
+ width: number;
51
+ height: number;
52
+ }
53
+ /**
54
+ * Union of all entity types that can be managed by the engine's
55
+ * {@link GameObjectRegister}.
56
+ *
57
+ * Covers both static entities ({@link Entity}) and physics-capable
58
+ * entities ({@link DynamicEntity}).
59
+ *
60
+ * @category Types
61
+ * @since 0.1.0
62
+ *
63
+ * @see {@link Entity} — base abstract entity
64
+ * @see {@link DynamicEntity} — entity with velocity and speed
65
+ */
7
66
  export type GameObject = Entity | DynamicEntity;
67
+ /**
68
+ * Discriminated union describing the shape of a collision volume.
69
+ *
70
+ * The `type` field acts as the discriminant:
71
+ *
72
+ * | `type` | Extra fields | Description |
73
+ * | ---------- | -------------------------- | ------------------------------ |
74
+ * | `"aabb"` | `width`, `height`, `offset?` | Axis-aligned bounding box |
75
+ * | `"circle"` | `radius`, `offset?` | Circle centred on the entity |
76
+ *
77
+ * @category Types
78
+ * @since 0.1.0
79
+ *
80
+ * @example AABB collider
81
+ * ```ts
82
+ * const box: ColliderShape = {
83
+ * type: "aabb",
84
+ * width: 32,
85
+ * height: 32,
86
+ * };
87
+ * ```
88
+ *
89
+ * @example Circle collider with offset
90
+ * ```ts
91
+ * const circle: ColliderShape = {
92
+ * type: "circle",
93
+ * radius: 16,
94
+ * offset: { x: 0, y: -4 },
95
+ * };
96
+ * ```
97
+ */
8
98
  export type ColliderShape = {
99
+ /** Discriminant for an axis-aligned bounding box. */
9
100
  type: "aabb";
101
+ /** Width of the bounding box in pixels. */
10
102
  width: number;
103
+ /** Height of the bounding box in pixels. */
11
104
  height: number;
105
+ /**
106
+ * Optional positional offset relative to the owning entity's origin.
107
+ * @defaultValue `{ x: 0, y: 0 }`
108
+ */
12
109
  offset?: Vector2;
13
110
  } | {
111
+ /** Discriminant for a circular collider. */
14
112
  type: "circle";
113
+ /** Radius of the circle in pixels. */
15
114
  radius: number;
115
+ /**
116
+ * Optional positional offset relative to the owning entity's origin.
117
+ * @defaultValue `{ x: 0, y: 0 }`
118
+ */
16
119
  offset?: Vector2;
17
120
  };
121
+ /**
122
+ * Payload delivered to a {@link Collidable.onCollision} callback when two
123
+ * colliders overlap.
124
+ *
125
+ * Provides references to both participating entities and their tag sets
126
+ * so the callback can determine the nature of the collision.
127
+ *
128
+ * @category Types
129
+ * @since 0.1.0
130
+ *
131
+ * @example Handling a collision
132
+ * ```ts
133
+ * function handleHit(info: CollisionInfo) {
134
+ * if (info.otherTags.has("enemy")) {
135
+ * console.log(`${info.self.id} was hit by ${info.other.id}`);
136
+ * }
137
+ * }
138
+ * ```
139
+ */
18
140
  export interface CollisionInfo {
141
+ /** The entity that *owns* this collision callback. */
19
142
  self: Entity;
143
+ /** The other entity involved in the collision. */
20
144
  other: Entity;
145
+ /** Tags belonging to {@link CollisionInfo.self | self}. */
21
146
  selfTags: Set<string>;
147
+ /** Tags belonging to {@link CollisionInfo.other | other}. */
22
148
  otherTags: Set<string>;
23
149
  }
150
+ /**
151
+ * Axis-aligned rectangle used internally by the collision detection
152
+ * system ({@link World}) to represent an entity's bounding volume in
153
+ * world-space.
154
+ *
155
+ * @category Types
156
+ * @since 0.1.0
157
+ *
158
+ * @see {@link World} — consumes these bounds during the detection pass
159
+ */
24
160
  export interface WorldBounds {
161
+ /** Left edge X coordinate. */
25
162
  x: number;
163
+ /** Top edge Y coordinate. */
26
164
  y: number;
165
+ /** Horizontal extent in pixels. */
27
166
  width: number;
167
+ /** Vertical extent in pixels. */
28
168
  height: number;
29
169
  }
30
170
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,MAAM,WAAW,OAAO;IACtB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AAEhD,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GACjE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,OAAO;IACtB,kDAAkD;IAClD,CAAC,EAAE,MAAM,CAAC;IACV,qEAAqE;IACrE,CAAC,EAAE,MAAM,CAAC;CACX;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,aAAa,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GACD;IACE,4CAA4C;IAC5C,IAAI,EAAE,QAAQ,CAAC;IACf,sCAAsC;IACtC,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEN;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACtB,6DAA6D;IAC7D,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,CAAC,EAAE,MAAM,CAAC;IACV,6BAA6B;IAC7B,CAAC,EAAE,MAAM,CAAC;IACV,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,iCAAiC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@dryanovski/gamefoo",
3
- "version": "0.0.1",
3
+ "version": "0.2.1",
4
4
  "description": "A lightweight 2D game engine with behavior-based component system",
5
5
  "license": "MIT",
6
+ "files": [
7
+ "dist"
8
+ ],
6
9
  "type": "module",
10
+ "sideEffects": false,
7
11
  "main": "./dist/index.js",
8
12
  "module": "./dist/index.js",
9
13
  "types": "./dist/index.d.ts",
@@ -13,24 +17,34 @@
13
17
  "import": "./dist/index.js"
14
18
  }
15
19
  },
16
- "files": [
17
- "dist"
18
- ],
19
20
  "publishConfig": {
20
21
  "access": "public"
21
22
  },
22
- "sideEffects": false,
23
23
  "scripts": {
24
- "dev": "bun --hot demo/server.ts",
25
- "build": "rm -rf dist && bun build ./index.ts --outdir dist --format esm --target browser --sourcemap=external && tsc -p tsconfig.build.json",
24
+ "dev": "bun --watch demos/server.ts",
25
+ "build": "rm -rf dist && bun build ./src/index.ts --outdir dist --format esm --target browser --sourcemap=external --splitting && tsc -p tsconfig.build.json",
26
26
  "typecheck": "tsc --noEmit",
27
27
  "typecheck:watch": "tsc --noEmit --watch",
28
- "lint": "bunx biome check .",
29
- "lint:fix": "bunx biome check --write --unsafe .",
30
- "format": "bunx biome format --write .",
28
+ "lint": "bunx biome check src/",
29
+ "lint:fix": "bunx biome check --write --unsafe src/",
30
+ "format": "bunx biome format --write src/",
31
31
  "check": "bun run typecheck && bun run lint",
32
32
  "prepublishOnly": "bun run check && bun run build",
33
- "prepare": "husky"
33
+ "prepare": "husky",
34
+ "docs:generate": "typedoc && tsx scripts/fix-api-frontmatter.ts && tsx scripts/collect-docs.ts",
35
+ "docs:build": "npm run docs:generate && astro build --root ./docs",
36
+ "docs:collect": "tsx scripts/collect-docs.ts",
37
+ "docs:dev": "npm run docs:generate && astro dev --root ./docs",
38
+ "docs:preview": "astro preview --root ./docs",
39
+ "docs:watch": "chokidar 'src/**/*.ts' -c 'bun run docs:generate' --initial"
40
+ },
41
+ "dependencies": {
42
+ "@microsoft/tsdoc": "^0.16.0",
43
+ "astro": "^5.18.0",
44
+ "chokidar-cli": "^3.0.0",
45
+ "tsx": "^4.21.0",
46
+ "typedoc": "^0.28.17",
47
+ "typedoc-plugin-markdown": "^4.10.0"
34
48
  },
35
49
  "devDependencies": {
36
50
  "@biomejs/biome": "^2.4.4",