1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2026-present FERS Contributors (see AUTHORS.md).
4export type SimObjectType =
13const TYPE_CODES: Record<SimObjectType, bigint> = {
23const CODE_TO_TYPE: Record<number, SimObjectType> = {
33const MAX_COUNTER = 0x0000ffffffffffffn;
35const counters: Record<SimObjectType, bigint> = {
45export const normalizeSimId = (value: unknown): string | null => {
46 if (typeof value === 'string') {
47 return /^\d+$/.test(value) ? value : null;
49 if (typeof value === 'number' && Number.isFinite(value)) {
50 return Math.trunc(value).toString();
55export const reserveSimId = (id: string): void => {
56 const parsed = BigInt(id);
57 const typeCode = Number(parsed >> 48n);
58 const counter = parsed & MAX_COUNTER;
59 const type = CODE_TO_TYPE[typeCode];
61 const next = counter + 1n;
62 if (next > counters[type]) {
63 counters[type] = next;
67export const seedSimIdCounters = (
68 ids: Array<string | null | undefined>
77export const generateSimId = (type: SimObjectType): string => {
78 const counter = counters[type];
79 if (counter > MAX_COUNTER) {
80 throw new Error(`SimId counter overflow for ${type}.`);
82 const id = (TYPE_CODES[type] << 48n) | counter;
83 counters[type] = counter + 1n;