feat(industry): add InventionTimeline singleton for tracking inventions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-08 23:44:44 +00:00
parent 66247276cd
commit b6a08c8bd8
2 changed files with 77 additions and 0 deletions
@@ -0,0 +1,44 @@
import { describe, it, expect } from 'vitest';
import { createInventionTimeline, type InventionTimeline } from '../inventionTimeline.js';
describe('InventionTimeline', () => {
it('starts empty', () => {
const timeline = createInventionTimeline();
expect(timeline.getAll()).toEqual([]);
});
it('records an invention entry', () => {
const timeline = createInventionTimeline();
timeline.record({
itemId: 'rope',
inventorEntityId: 1,
inventorName: 'Gwen',
tick: 500,
day: 2,
});
const all = timeline.getAll();
expect(all).toHaveLength(1);
expect(all[0].itemId).toBe('rope');
expect(all[0].inventorName).toBe('Gwen');
});
it('counts inventions per entity', () => {
const timeline = createInventionTimeline();
timeline.record({ itemId: 'rope', inventorEntityId: 1, inventorName: 'Gwen', tick: 500, day: 2 });
timeline.record({ itemId: 'clay', inventorEntityId: 1, inventorName: 'Gwen', tick: 600, day: 2 });
timeline.record({ itemId: 'kiln', inventorEntityId: 2, inventorName: 'Bram', tick: 700, day: 3 });
expect(timeline.countByEntity(1)).toBe(2);
expect(timeline.countByEntity(2)).toBe(1);
expect(timeline.countByEntity(3)).toBe(0);
});
it('returns entries in insertion order', () => {
const timeline = createInventionTimeline();
timeline.record({ itemId: 'a', inventorEntityId: 1, inventorName: 'X', tick: 300, day: 1 });
timeline.record({ itemId: 'b', inventorEntityId: 2, inventorName: 'Y', tick: 100, day: 1 });
const all = timeline.getAll();
expect(all[0].tick).toBe(300);
expect(all[1].tick).toBe(100);
});
});
+33
View File
@@ -0,0 +1,33 @@
import type { EntityId } from '@dflike/shared';
export interface InventionEntry {
itemId: string;
inventorEntityId: EntityId;
inventorName: string;
tick: number;
day: number;
}
export interface InventionTimeline {
record(entry: InventionEntry): void;
getAll(): InventionEntry[];
countByEntity(entityId: EntityId): number;
}
export function createInventionTimeline(): InventionTimeline {
const entries: InventionEntry[] = [];
return {
record(entry: InventionEntry): void {
entries.push(entry);
},
getAll(): InventionEntry[] {
return [...entries];
},
countByEntity(entityId: EntityId): number {
return entries.filter(e => e.inventorEntityId === entityId).length;
},
};
}