@puzzmo/sdk 1.0.18 → 1.0.20
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/createSimulator-HQPoM1pd.cjs.map +1 -1
- package/dist/{createSimulator-BwucCTnM.js → createSimulator-jeSc_X3r.js} +13 -26
- package/dist/createSimulator-jeSc_X3r.js.map +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inputs/index.cjs.map +1 -1
- package/dist/inputs/index.d.ts +17 -14
- package/dist/inputs/index.d.ts.map +1 -1
- package/dist/inputs/index.js +26 -21
- package/dist/inputs/index.js.map +1 -1
- package/dist/inputs/types.d.ts +47 -20
- package/dist/inputs/types.d.ts.map +1 -1
- package/dist/keyboard.d.ts +4 -4
- package/dist/simulator/createSimulator.d.ts +4 -1
- package/dist/simulator/createSimulator.d.ts.map +1 -1
- package/dist/simulator/fixtures.d.ts +4 -12
- package/dist/simulator/fixtures.d.ts.map +1 -1
- package/dist/simulator/index.js +1 -1
- package/dist/simulator/standalone.cjs.map +1 -1
- package/dist/simulator/standalone.d.ts.map +1 -1
- package/dist/simulator/standalone.js +2 -1
- package/dist/simulator/standalone.js.map +1 -1
- package/dist/simulator/views/DataView.d.ts.map +1 -1
- package/dist/simulator/views/ThemeView.d.ts.map +1 -1
- package/dist/simulator/views/ThumbView.d.ts.map +1 -1
- package/dist/types.d.ts +57 -43
- package/dist/types.d.ts.map +1 -1
- package/dist/vite.cjs +2 -2
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.ts +8 -1
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +22 -9
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/dist/createSimulator-BwucCTnM.js.map +0 -1
package/dist/inputs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/inputs/encodings.ts","../../src/inputs/encoder.ts","../../src/inputs/decoder.ts","../../src/inputs/migration.ts","../../src/inputs/types.ts","../../src/inputs/index.ts"],"sourcesContent":["import { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from \"lz-string\"\n\nexport function encodeBitArrayToHex(bits: boolean[]): string {\n if (bits.length === 0) return \"0\"\n\n let hex = \"\"\n for (let i = 0; i < bits.length; i += 4) {\n let nibble = 0\n for (let j = 0; j < 4 && i + j < bits.length; j++) {\n if (bits[i + j]) {\n nibble |= 1 << j\n }\n }\n hex += nibble.toString(16)\n }\n\n return hex || \"0\"\n}\n\nexport function decodeBitArrayFromHex(hex: string, length: number): boolean[] {\n const bits: boolean[] = []\n\n for (let i = 0; i < length; i++) {\n const hexIndex = Math.floor(i / 4)\n const bitIndex = i % 4\n const nibble = parseInt(hex[hexIndex] || \"0\", 16)\n bits.push((nibble & (1 << bitIndex)) !== 0)\n }\n\n return bits\n}\n\nexport function encodeIntArray(arr: number[]): string {\n if (arr.length === 0) return \"\"\n\n const nonZero = arr.map((val, idx) => ({ val, idx })).filter((item) => item.val !== 0)\n\n if (nonZero.length === 0) return \"\"\n if (nonZero.length > arr.length / 2) {\n return arr.join(\",\")\n }\n\n return nonZero.map((item) => `${item.idx}=${item.val}`).join(\",\")\n}\n\nexport function decodeIntArray(str: string, defaultLength?: number): number[] {\n if (!str) return defaultLength ? Array.from({ length: defaultLength }, () => 0) : []\n\n if (str.includes(\"=\")) {\n const result = defaultLength ? Array.from({ length: defaultLength }, () => 0) : []\n const pairs = str.split(\",\")\n for (const pair of pairs) {\n const [idxStr, valStr] = pair.split(\"=\")\n const idx = Number(idxStr)\n const val = Number(valStr)\n if (!isNaN(idx) && !isNaN(val)) {\n result[idx] = val\n }\n }\n return result\n }\n\n return str.split(\",\").map((x) => Number(x))\n}\n\nexport function encodeStringArray(arr: string[], delimiter = \",\"): string {\n return arr.join(delimiter)\n}\n\nexport function decodeStringArray(str: string, delimiter = \",\"): string[] {\n if (!str) return []\n return str.split(delimiter)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- JSON can encode any data\nexport function encodeJson(data: any): string {\n const json = JSON.stringify(data)\n return compressToEncodedURIComponent(json)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- JSON can decode to any data\nexport function decodeJson(str: string): any {\n if (!str) return undefined\n const json = decompressFromEncodedURIComponent(str)\n return json ? JSON.parse(json) : undefined\n}\n\nexport function encodeSparseMap<T>(map: Record<string, T>, encodeValue: (val: T) => string, orderedKeys?: string[]): string {\n const entries = Object.entries(map).filter(([_, val]) => val !== null && val !== undefined)\n\n if (orderedKeys) {\n // Use numeric indices instead of string keys\n const indexedEntries = entries\n .map(([key, val]) => {\n const idx = orderedKeys.indexOf(key)\n if (idx === -1) return null\n return `${idx}=${encodeValue(val)}`\n })\n .filter((entry): entry is string => entry !== null)\n\n return indexedEntries.join(\",\")\n } else {\n // Fall back to string keys\n return entries.map(([key, val]) => `${key}=${encodeValue(val)}`).join(\";\")\n }\n}\n\nexport function decodeSparseMap<T>(str: string, decodeValue: (val: string) => T, orderedKeys?: string[]): Record<string, T> {\n if (!str) return {}\n\n const result: Record<string, T> = {}\n\n if (orderedKeys) {\n // Decode numeric indices\n const entries = str.split(\",\")\n for (const entry of entries) {\n if (!entry) continue\n const [idxStr, val] = entry.split(\"=\")\n const idx = Number(idxStr)\n if (!isNaN(idx) && val && orderedKeys[idx]) {\n result[orderedKeys[idx]] = decodeValue(val)\n }\n }\n } else {\n // Decode string keys\n const entries = str.split(\";\")\n for (const entry of entries) {\n if (!entry) continue\n const [key, val] = entry.split(\"=\")\n if (key && val) {\n result[key] = decodeValue(val)\n }\n }\n }\n\n return result\n}\n","import type { Schema, FieldType } from \"./types\"\nimport { encodeBitArrayToHex, encodeIntArray, encodeStringArray, encodeSparseMap, encodeJson } from \"./encodings\"\n\nexport function encodeField(value: any, fieldType: FieldType, context?: any): string {\n switch (fieldType.type) {\n case \"bitArray\":\n return encodeBitArrayToHex(value)\n\n case \"intArray\":\n return encodeIntArray(value)\n\n case \"int\":\n return String(value)\n\n case \"string\":\n return String(value)\n\n case \"stringArray\":\n return encodeStringArray(value, fieldType.delimiter)\n\n case \"sparseMap\":\n return encodeSparseMap(value, fieldType.valueEncoder, context?.keys)\n\n case \"json\":\n return encodeJson(value)\n\n default:\n throw new Error(`Unknown field type: ${(fieldType as any).type}`)\n }\n}\n\nexport function encode<TData>(schema: Schema<TData>, data: TData, context?: Record<string, any>): string {\n const delimiter = schema.delimiter || \":\"\n const fieldNames = Object.keys(schema.fields) as (keyof TData)[]\n\n const encodedFields = fieldNames.map((fieldName) => {\n const fieldType = schema.fields[fieldName]\n const value = data[fieldName]\n const fieldContext = context?.[fieldName as string]\n return encodeField(value, fieldType, fieldContext)\n })\n\n return `v${schema.version}${delimiter}${encodedFields.join(delimiter)}`\n}\n","import type { Schema, FieldType } from \"./types\"\nimport { decodeBitArrayFromHex, decodeIntArray, decodeStringArray, decodeSparseMap, decodeJson } from \"./encodings\"\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- context is dynamic and return type depends on fieldType\nexport function decodeField(value: string, fieldType: FieldType, context?: any): any {\n switch (fieldType.type) {\n case \"bitArray\":\n if (!context?.length) {\n throw new Error(\"bitArray requires length in context\")\n }\n return decodeBitArrayFromHex(value, context.length)\n\n case \"intArray\":\n return decodeIntArray(value, context?.length)\n\n case \"int\":\n return Number(value)\n\n case \"string\":\n return value\n\n case \"stringArray\":\n return decodeStringArray(value, fieldType.delimiter)\n\n case \"sparseMap\":\n return decodeSparseMap(value, fieldType.valueDecoder, context?.keys)\n\n case \"json\":\n return decodeJson(value)\n\n default:\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- used in error message for invalid type\n throw new Error(`Unknown field type: ${(fieldType as any).type}`)\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- context values are dynamic\nexport function decode<TData>(schema: Schema<TData>, inputString: string, context?: Record<string, any>): TData {\n const delimiter = schema.delimiter || \":\"\n const parts = inputString.split(delimiter)\n\n const versionPart = parts[0]\n const versionMatch = versionPart.match(/^v(\\d+)$/)\n if (!versionMatch) {\n throw new Error(`Invalid input string format: ${versionPart}`)\n }\n\n const version = Number(versionMatch[1])\n if (version !== schema.version) {\n throw new Error(`Version mismatch: expected v${schema.version}, got v${version}. ` + `Make sure to run migrations first.`)\n }\n\n const fieldNames = Object.keys(schema.fields) as (keyof TData)[]\n const data = {} as TData\n\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i]\n const fieldType = schema.fields[fieldName]\n const fieldValue = parts[i + 1] || \"\"\n\n const fieldContext = context?.[fieldName as string]\n data[fieldName] = decodeField(fieldValue, fieldType, fieldContext)\n }\n\n return data\n}\n","import type { Schema } from \"./types\"\nimport { encode } from \"./encoder\"\nimport { decode } from \"./decoder\"\n\nexport function createMigrator<TData>(schema: Schema<TData>) {\n return function migrate(inputString: string, context?: Record<string, any>): string {\n const versionMatch = inputString.match(/^v(\\d+)/)\n if (!versionMatch) {\n throw new Error(\"Invalid input string: no version found\")\n }\n\n const currentVersion = Number(versionMatch[1])\n\n if (currentVersion === schema.version) {\n return inputString\n }\n\n if (!schema.migrations) {\n throw new Error(`No migrations defined for schema. Cannot migrate from v${currentVersion} to v${schema.version}`)\n }\n\n // Data type changes at each migration step (v0 → v1 → v2, etc.)\n // TypeScript can't track these transformations statically, so we use `any`\n // Migrations are developer-written and tested to maintain type safety through the chain\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let data: any = decode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n { ...schema, version: currentVersion } as Schema<any>,\n inputString,\n context,\n )\n\n for (let v = currentVersion; v < schema.version; v++) {\n const migration = schema.migrations[v]\n if (migration) {\n data = migration(data)\n }\n }\n\n return encode(schema, data, context)\n }\n}\n","/**\n * Encodes boolean arrays as compact hexadecimal strings.\n *\n * **When to use:**\n * - Revealed/hidden state of game tiles\n * - Feature flags or settings\n * - Any boolean array where order matters\n *\n * **Encoding:**\n * - Packs 4 bits per hex character (75% size reduction)\n * - Example: [true, false, false, false, false, true, false, false] → \"12\"\n *\n * **Decoding:**\n * - Requires length in context: `{ fieldName: { length: 100 } }`\n */\nexport type BitArrayFieldType = {\n type: \"bitArray\"\n}\n\n/**\n * Encodes integer arrays with automatic sparse optimization.\n *\n * **When to use:**\n * - Arrays of numeric values (scores, counts, experience)\n * - Sparse data (mostly zeros)\n * - Dense data (will auto-fallback to CSV)\n *\n * **Encoding:**\n * - Uses decimal (base-10) numbers separated by commas\n * - Smart sparse: If >50% zeros, uses `index=value` pairs (e.g., \"2=5,4=3\")\n * - Dense fallback: If not beneficial, uses CSV (e.g., \"1,2,3,4\")\n * - Empty arrays encode as empty string\n *\n * **Decoding:**\n * - Requires length in context for sparse format: `{ fieldName: { length: 100 } }`\n * - CSV format decodes without context\n */\nexport type IntArrayFieldType = {\n type: \"intArray\"\n}\n\n/**\n * Encodes single integer values.\n *\n * **When to use:**\n * - Single numeric values (score, level, count)\n * - Non-negative integers only\n *\n * **Encoding:**\n * - Uses decimal (base-10) representation\n * - Example: 42 → \"42\"\n */\nexport type IntFieldType = {\n type: \"int\"\n}\n\n/**\n * Encodes string values as-is.\n *\n * **When to use:**\n * - Single string values (name, color, mode)\n * - Short identifiers\n *\n * **Warning:**\n * - Strings containing the schema delimiter (default ':') will break parsing\n * - Consider using a custom delimiter or different encoding for such strings\n */\nexport type StringFieldType = {\n type: \"string\"\n}\n\n/**\n * Encodes arrays of strings.\n *\n * **When to use:**\n * - Lists of tags, categories, or identifiers\n * - Ordered collections of strings\n *\n * **Encoding:**\n * - Uses comma delimiter by default\n * - Custom delimiter can be specified to avoid conflicts\n *\n * **Warning:**\n * - Strings containing the delimiter will break parsing\n * - Use custom delimiter to avoid conflicts\n */\nexport type StringArrayFieldType = {\n type: \"stringArray\"\n delimiter?: string\n}\n\n/**\n * Encodes sparse key-value maps with custom value encoding.\n *\n * **When to use:**\n * - Tile annotations, cell metadata\n * - Any sparse mapping where most keys don't have values\n * - Custom object types that need specialized encoding\n *\n * **Encoding:**\n * - With context keys: Uses numeric indices (e.g., `0=2.1,5=3.0`)\n * - Without context: Uses string keys (e.g., `key1=val1;key2=val2`)\n * - Only stores non-empty entries\n * - Keys are always strings in the data, converted to indices when context provides ordered keys\n * - valueEncoder: Convert your object to a string\n * - valueDecoder: Parse string back to your object\n *\n * **Optimization:**\n * Provide ordered keys in context to use numeric indices instead of string keys:\n * ```typescript\n * const { encode, decode } = createEncoder(schema, {\n * annotations: { keys: tileIds } // Ordered list of possible keys\n * })\n * ```\n *\n * **Example:**\n * ```typescript\n * annotations: {\n * type: 'sparseMap',\n * valueEncoder: (ann) => `${ann.level}.${ann.color}`,\n * valueDecoder: (str) => {\n * const [level, color] = str.split('.').map(Number)\n * return { level, color }\n * }\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for value type\nexport type SparseMapFieldType<TValue = any> = {\n type: \"sparseMap\"\n valueEncoder: (value: TValue) => string\n valueDecoder: (str: string) => TValue\n}\n\n/**\n * Encodes arbitrary data as JSON with automatic compression.\n *\n * **When to use:**\n * - Complex nested structures\n * - Fallback for data that doesn't fit other types\n * - Temporary solution before implementing custom encoding\n *\n * **Encoding:**\n * - Converts data to JSON string\n * - Automatically compresses with lz-string\n * - Helps reduce size of complex objects\n *\n * **Warning:**\n * - Still larger than specialized encodings even with compression\n * - Use only when necessary\n * - Consider creating custom sparseMap encoding instead\n */\nexport type JsonFieldType = {\n type: \"json\"\n}\n\n/**\n * Union of all available field types.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for field values\nexport type FieldType<TValue = any> =\n | BitArrayFieldType\n | IntArrayFieldType\n | IntFieldType\n | StringFieldType\n | StringArrayFieldType\n | SparseMapFieldType<TValue>\n | JsonFieldType\n\n/**\n * Function that migrates data from one version to another.\n *\n * **When to use:**\n * - Add new fields with default values\n * - Transform existing field values\n * - Rename or restructure fields\n *\n * **Important:**\n * - Migrations operate on decoded data objects, not strings\n * - Each migration goes from version N to version N+1\n * - Migrations are applied sequentially\n *\n * **Example:**\n * ```typescript\n * migrations: {\n * 0: (oldData) => ({\n * ...oldData,\n * newField: 'default value'\n * }),\n * 1: (oldData) => ({\n * ...oldData,\n * name: oldData.name.toUpperCase()\n * })\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameters for migration input/output\nexport type DataMigration<TFrom = any, TTo = any> = (data: TFrom) => TTo\n\n/**\n * Map of version numbers to migration functions.\n *\n * Keys are the source version numbers (0, 1, 2, etc.)\n * Values are functions that migrate from that version to the next\n */\nexport type MigrationMap = {\n [fromVersion: number]: DataMigration\n}\n\n/**\n * Complete schema definition for encoding/decoding data.\n *\n * **Basic usage:**\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * name: { type: 'string' },\n * age: { type: 'int' }\n * }\n * })\n * ```\n *\n * **With custom delimiter:**\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * delimiter: '|', // Use | instead of :\n * fields: { ... }\n * })\n * ```\n *\n * **With migrations:**\n * ```typescript\n * const schema = defineSchema({\n * version: 2,\n * fields: {\n * name: { type: 'string' },\n * value: { type: 'int' }\n * },\n * migrations: {\n * 0: (old) => ({ ...old, value: 0 }),\n * 1: (old) => ({ ...old, name: old.name.toUpperCase() })\n * }\n * })\n * ```\n *\n * @param version - Current schema version (increment when making breaking changes)\n * @param delimiter - Character to separate fields (default: ':')\n * @param fields - Map of field names to field type definitions\n * @param migrations - Optional map of version migrations\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for schema data, and field values need 'any' for flexibility\nexport type Schema<TData = any> = {\n version: number\n delimiter?: string\n fields: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Field values can be any type\n [K in keyof TData]: FieldType<any>\n }\n migrations?: MigrationMap\n}\n\n/**\n * Result of creating an encoder from a schema.\n *\n * **Usage:**\n * ```typescript\n * const { encode, decode, migrate } = createEncoder(schema, context)\n *\n * // Encode data to string\n * const inputString = encode(data)\n *\n * // Decode string to data\n * const data = decode(inputString)\n *\n * // Migrate old version to current version\n * const currentVersion = migrate(oldInputString)\n * ```\n */\nexport type EncoderResult<TData> = {\n encode: (data: TData) => string\n decode: (str: string) => TData\n migrate: (str: string) => string\n}\n\n/**\n * Define a typed schema for encoding/decoding game state.\n *\n * **Purpose:**\n * - Provides type inference for encode/decode functions\n * - Documents the structure of your input strings\n * - Enables version migrations\n *\n * **Example:**\n * ```typescript\n * type GameData = {\n * revealed: boolean[]\n * score: number\n * annotations: Record<string, Annotation>\n * }\n *\n * export const schema = defineSchema<GameData>({\n * version: 1,\n * fields: {\n * revealed: { type: 'bitArray' },\n * score: { type: 'int' },\n * annotations: {\n * type: 'sparseMap',\n * valueEncoder: (ann) => `${ann.level}.${ann.color}`,\n * valueDecoder: (str) => {\n * const [level, color] = str.split('.').map(Number)\n * return { level, color }\n * }\n * }\n * }\n * })\n * ```\n */\nexport function defineSchema<TData>(schema: Schema<TData>): Schema<TData> {\n return schema\n}\n","import type { Schema, EncoderResult } from \"./types\"\nimport { encode } from \"./encoder\"\nimport { decode } from \"./decoder\"\nimport { createMigrator } from \"./migration\"\n\nexport { defineSchema } from \"./types\"\nexport type {\n Schema,\n EncoderResult,\n FieldType,\n BitArrayFieldType,\n IntArrayFieldType,\n IntFieldType,\n StringFieldType,\n StringArrayFieldType,\n SparseMapFieldType,\n JsonFieldType,\n DataMigration,\n MigrationMap,\n} from \"./types\"\n\n/**\n * Create an encoder/decoder for a schema-defined data structure.\n *\n * **Basic usage:**\n * ```typescript\n * import { defineSchema, createEncoder } from '@puzzmo/sdk/inputs'\n *\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * name: { type: 'string' },\n * age: { type: 'int' }\n * }\n * })\n *\n * const { encode, decode } = createEncoder(schema)\n *\n * const data = { name: 'Alice', age: 30 }\n * const inputString = encode(data) // \"v1:Alice:30\"\n * const decoded = decode(inputString) // { name: 'Alice', age: 30 }\n * ```\n *\n * **With context (for length-dependent fields):**\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * revealed: { type: 'bitArray' },\n * scores: { type: 'intArray' }\n * }\n * })\n *\n * const { encode, decode } = createEncoder(schema, {\n * revealed: { length: 100 }, // Required for bitArray decoding\n * scores: { length: 10 }, // Required for sparse intArray decoding\n * annotations: { keys: tileIds } // Optional: optimize sparseMap with numeric indices\n * })\n * ```\n *\n * **With migrations:**\n * ```typescript\n * const { encode, decode, migrate } = createEncoder(schema)\n *\n * const oldString = \"v0:Alice:30\"\n * const migrated = migrate(oldString) // \"v1:Alice:30:default\"\n * const data = decode(migrated)\n * ```\n *\n * @param schema - Schema definition created with defineSchema()\n * @param context - Optional context for decoding (lengths for bitArray/intArray)\n * @returns Object with encode, decode, and migrate functions\n */\nexport function createEncoder<TData>(\n schema: Schema<TData>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Context values can be any shape depending on field types\n context?: Record<string, any>,\n): EncoderResult<TData> {\n const migrator = createMigrator(schema)\n\n return {\n encode: (data: TData) => encode(schema, data, context),\n decode: (str: string) => decode(schema, str, context),\n migrate: (str: string) => migrator(str, context),\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/inputs/encodings.ts","../../src/inputs/encoder.ts","../../src/inputs/decoder.ts","../../src/inputs/migration.ts","../../src/inputs/types.ts","../../src/inputs/index.ts"],"sourcesContent":["import { compressToEncodedURIComponent, decompressFromEncodedURIComponent } from \"lz-string\"\n\nexport function encodeBitArrayToHex(bits: boolean[]): string {\n if (bits.length === 0) return \"0\"\n\n let hex = \"\"\n for (let i = 0; i < bits.length; i += 4) {\n let nibble = 0\n for (let j = 0; j < 4 && i + j < bits.length; j++) {\n if (bits[i + j]) {\n nibble |= 1 << j\n }\n }\n hex += nibble.toString(16)\n }\n\n return hex || \"0\"\n}\n\nexport function decodeBitArrayFromHex(hex: string, length: number): boolean[] {\n const bits: boolean[] = []\n\n for (let i = 0; i < length; i++) {\n const hexIndex = Math.floor(i / 4)\n const bitIndex = i % 4\n const nibble = parseInt(hex[hexIndex] || \"0\", 16)\n bits.push((nibble & (1 << bitIndex)) !== 0)\n }\n\n return bits\n}\n\nexport function encodeIntArray(arr: number[]): string {\n if (arr.length === 0) return \"\"\n\n const nonZero = arr.map((val, idx) => ({ val, idx })).filter((item) => item.val !== 0)\n\n if (nonZero.length === 0) return \"\"\n if (nonZero.length > arr.length / 2) {\n return arr.join(\",\")\n }\n\n return nonZero.map((item) => `${item.idx}=${item.val}`).join(\",\")\n}\n\nexport function decodeIntArray(str: string, defaultLength?: number): number[] {\n if (!str) return defaultLength ? Array.from({ length: defaultLength }, () => 0) : []\n\n if (str.includes(\"=\")) {\n const result = defaultLength ? Array.from({ length: defaultLength }, () => 0) : []\n const pairs = str.split(\",\")\n for (const pair of pairs) {\n const [idxStr, valStr] = pair.split(\"=\")\n const idx = Number(idxStr)\n const val = Number(valStr)\n if (!isNaN(idx) && !isNaN(val)) {\n result[idx] = val\n }\n }\n return result\n }\n\n return str.split(\",\").map((x) => Number(x))\n}\n\nexport function encodeStringArray(arr: string[], delimiter = \",\"): string {\n return arr.join(delimiter)\n}\n\nexport function decodeStringArray(str: string, delimiter = \",\"): string[] {\n if (!str) return []\n return str.split(delimiter)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- JSON can encode any data\nexport function encodeJson(data: any): string {\n const json = JSON.stringify(data)\n return compressToEncodedURIComponent(json)\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- JSON can decode to any data\nexport function decodeJson(str: string): any {\n if (!str) return undefined\n const json = decompressFromEncodedURIComponent(str)\n return json ? JSON.parse(json) : undefined\n}\n\nexport function encodeSparseMap<T>(map: Record<string, T>, encodeValue: (val: T) => string, orderedKeys?: string[]): string {\n const entries = Object.entries(map).filter(([_, val]) => val !== null && val !== undefined)\n\n if (orderedKeys) {\n // Use numeric indices instead of string keys\n const indexedEntries = entries\n .map(([key, val]) => {\n const idx = orderedKeys.indexOf(key)\n if (idx === -1) return null\n return `${idx}=${encodeValue(val)}`\n })\n .filter((entry): entry is string => entry !== null)\n\n return indexedEntries.join(\",\")\n } else {\n // Fall back to string keys\n return entries.map(([key, val]) => `${key}=${encodeValue(val)}`).join(\";\")\n }\n}\n\nexport function decodeSparseMap<T>(str: string, decodeValue: (val: string) => T, orderedKeys?: string[]): Record<string, T> {\n if (!str) return {}\n\n const result: Record<string, T> = {}\n\n if (orderedKeys) {\n // Decode numeric indices\n const entries = str.split(\",\")\n for (const entry of entries) {\n if (!entry) continue\n const [idxStr, val] = entry.split(\"=\")\n const idx = Number(idxStr)\n if (!isNaN(idx) && val && orderedKeys[idx]) {\n result[orderedKeys[idx]] = decodeValue(val)\n }\n }\n } else {\n // Decode string keys\n const entries = str.split(\";\")\n for (const entry of entries) {\n if (!entry) continue\n const [key, val] = entry.split(\"=\")\n if (key && val) {\n result[key] = decodeValue(val)\n }\n }\n }\n\n return result\n}\n","import type { Schema, FieldType } from \"./types\"\nimport { encodeBitArrayToHex, encodeIntArray, encodeStringArray, encodeSparseMap, encodeJson } from \"./encodings\"\n\nexport function encodeField(value: any, fieldType: FieldType, context?: any): string {\n switch (fieldType.type) {\n case \"bitArray\":\n return encodeBitArrayToHex(value)\n\n case \"intArray\":\n return encodeIntArray(value)\n\n case \"int\":\n return String(value)\n\n case \"string\":\n return String(value)\n\n case \"stringArray\":\n return encodeStringArray(value, fieldType.delimiter)\n\n case \"sparseMap\":\n return encodeSparseMap(value, fieldType.valueEncoder, context?.keys)\n\n case \"json\":\n return encodeJson(value)\n\n default:\n throw new Error(`Unknown field type: ${(fieldType as any).type}`)\n }\n}\n\nexport function encode<TData>(schema: Schema<TData>, data: TData, context?: Record<string, any>): string {\n const delimiter = schema.delimiter || \":\"\n const fieldNames = Object.keys(schema.fields) as (keyof TData)[]\n\n const encodedFields = fieldNames.map((fieldName) => {\n const fieldType = schema.fields[fieldName]\n const value = data[fieldName]\n const fieldContext = context?.[fieldName as string]\n return encodeField(value, fieldType, fieldContext)\n })\n\n return `v${schema.version}${delimiter}${encodedFields.join(delimiter)}`\n}\n","import type { Schema, FieldType } from \"./types\"\nimport { decodeBitArrayFromHex, decodeIntArray, decodeStringArray, decodeSparseMap, decodeJson } from \"./encodings\"\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- context is dynamic and return type depends on fieldType\nexport function decodeField(value: string, fieldType: FieldType, context?: any): any {\n switch (fieldType.type) {\n case \"bitArray\":\n if (!context?.length) {\n throw new Error(\"bitArray requires length in context\")\n }\n return decodeBitArrayFromHex(value, context.length)\n\n case \"intArray\":\n return decodeIntArray(value, context?.length)\n\n case \"int\":\n return Number(value)\n\n case \"string\":\n return value\n\n case \"stringArray\":\n return decodeStringArray(value, fieldType.delimiter)\n\n case \"sparseMap\":\n return decodeSparseMap(value, fieldType.valueDecoder, context?.keys)\n\n case \"json\":\n return decodeJson(value)\n\n default:\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- used in error message for invalid type\n throw new Error(`Unknown field type: ${(fieldType as any).type}`)\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- context values are dynamic\nexport function decode<TData>(schema: Schema<TData>, inputString: string, context?: Record<string, any>): TData {\n const delimiter = schema.delimiter || \":\"\n const parts = inputString.split(delimiter)\n\n const versionPart = parts[0]\n const versionMatch = versionPart.match(/^v(\\d+)$/)\n if (!versionMatch) {\n throw new Error(`Invalid input string format: ${versionPart}`)\n }\n\n const version = Number(versionMatch[1])\n if (version !== schema.version) {\n throw new Error(`Version mismatch: expected v${schema.version}, got v${version}. ` + `Make sure to run migrations first.`)\n }\n\n const fieldNames = Object.keys(schema.fields) as (keyof TData)[]\n const data = {} as TData\n\n for (let i = 0; i < fieldNames.length; i++) {\n const fieldName = fieldNames[i]\n const fieldType = schema.fields[fieldName]\n const fieldValue = parts[i + 1] || \"\"\n\n const fieldContext = context?.[fieldName as string]\n data[fieldName] = decodeField(fieldValue, fieldType, fieldContext)\n }\n\n return data\n}\n","import type { Schema } from \"./types\"\nimport { encode } from \"./encoder\"\nimport { decode } from \"./decoder\"\n\nexport function createMigrator<TData>(schema: Schema<TData>) {\n return function migrate(inputString: string, context?: Record<string, any>): string {\n const versionMatch = inputString.match(/^v(\\d+)/)\n if (!versionMatch) {\n throw new Error(\"Invalid input string: no version found\")\n }\n\n const currentVersion = Number(versionMatch[1])\n\n if (currentVersion === schema.version) {\n return inputString\n }\n\n if (!schema.migrations) {\n throw new Error(`No migrations defined for schema. Cannot migrate from v${currentVersion} to v${schema.version}`)\n }\n\n // Data type changes at each migration step (v0 → v1 → v2, etc.)\n // TypeScript can't track these transformations statically, so we use `any`\n // Migrations are developer-written and tested to maintain type safety through the chain\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let data: any = decode(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n { ...schema, version: currentVersion } as Schema<any>,\n inputString,\n context,\n )\n\n for (let v = currentVersion; v < schema.version; v++) {\n const migration = schema.migrations[v]\n if (migration) {\n data = migration(data)\n }\n }\n\n return encode(schema, data, context)\n }\n}\n","/**\n * Encodes boolean arrays as compact hexadecimal strings.\n *\n * **When to use:**\n *\n * - Revealed/hidden state of game tiles\n * - Feature flags or settings\n * - Any boolean array where order matters\n *\n * **Encoding:**\n *\n * - Packs 4 bits per hex character (75% size reduction)\n * - Example: [true, false, false, false, false, true, false, false] → \"12\"\n *\n * **Decoding:**\n *\n * - Requires length in context: `{ fieldName: { length: 100 } }`\n */\nexport type BitArrayFieldType = {\n type: \"bitArray\"\n}\n\n/**\n * Encodes integer arrays with automatic sparse optimization.\n *\n * **When to use:**\n *\n * - Arrays of numeric values (scores, counts, experience)\n * - Sparse data (mostly zeros)\n * - Dense data (will auto-fallback to CSV)\n *\n * **Encoding:**\n *\n * - Uses decimal (base-10) numbers separated by commas\n * - Smart sparse: If >50% zeros, uses `index=value` pairs (e.g., \"2=5,4=3\")\n * - Dense fallback: If not beneficial, uses CSV (e.g., \"1,2,3,4\")\n * - Empty arrays encode as empty string\n *\n * **Decoding:**\n *\n * - Requires length in context for sparse format: `{ fieldName: { length: 100 } }`\n * - CSV format decodes without context\n */\nexport type IntArrayFieldType = {\n type: \"intArray\"\n}\n\n/**\n * Encodes single integer values.\n *\n * **When to use:**\n *\n * - Single numeric values (score, level, count)\n * - Non-negative integers only\n *\n * **Encoding:**\n *\n * - Uses decimal (base-10) representation\n * - Example: 42 → \"42\"\n */\nexport type IntFieldType = {\n type: \"int\"\n}\n\n/**\n * Encodes string values as-is.\n *\n * **When to use:**\n *\n * - Single string values (name, color, mode)\n * - Short identifiers\n *\n * **Warning:**\n *\n * - Strings containing the schema delimiter (default ':') will break parsing\n * - Consider using a custom delimiter or different encoding for such strings\n */\nexport type StringFieldType = {\n type: \"string\"\n}\n\n/**\n * Encodes arrays of strings.\n *\n * **When to use:**\n *\n * - Lists of tags, categories, or identifiers\n * - Ordered collections of strings\n *\n * **Encoding:**\n *\n * - Uses comma delimiter by default\n * - Custom delimiter can be specified to avoid conflicts\n *\n * **Warning:**\n *\n * - Strings containing the delimiter will break parsing\n * - Use custom delimiter to avoid conflicts\n */\nexport type StringArrayFieldType = {\n type: \"stringArray\"\n delimiter?: string\n}\n\n/**\n * Encodes sparse key-value maps with custom value encoding.\n *\n * **When to use:**\n *\n * - Tile annotations, cell metadata\n * - Any sparse mapping where most keys don't have values\n * - Custom object types that need specialized encoding\n *\n * **Encoding:**\n *\n * - With context keys: Uses numeric indices (e.g., `0=2.1,5=3.0`)\n * - Without context: Uses string keys (e.g., `key1=val1;key2=val2`)\n * - Only stores non-empty entries\n * - Keys are always strings in the data, converted to indices when context provides ordered keys\n * - ValueEncoder: Convert your object to a string\n * - ValueDecoder: Parse string back to your object\n *\n * **Optimization:**\n * Provide ordered keys in context to use numeric indices instead of string keys:\n *\n * ```typescript\n * const { encode, decode } = createEncoder(schema, {\n * annotations: { keys: tileIds }, // Ordered list of possible keys\n * })\n * ```\n *\n * **Example:**\n *\n * ```typescript\n * annotations: {\n * type: 'sparseMap',\n * valueEncoder: (ann) => `${ann.level}.${ann.color}`,\n * valueDecoder: (str) => {\n * const [level, color] = str.split('.').map(Number)\n * return { level, color }\n * }\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for value type\nexport type SparseMapFieldType<TValue = any> = {\n type: \"sparseMap\"\n valueEncoder: (value: TValue) => string\n valueDecoder: (str: string) => TValue\n}\n\n/**\n * Encodes arbitrary data as JSON with automatic compression.\n *\n * **When to use:**\n *\n * - Complex nested structures\n * - Fallback for data that doesn't fit other types\n * - Temporary solution before implementing custom encoding\n *\n * **Encoding:**\n *\n * - Converts data to JSON string\n * - Automatically compresses with lz-string\n * - Helps reduce size of complex objects\n *\n * **Warning:**\n *\n * - Still larger than specialized encodings even with compression\n * - Use only when necessary\n * - Consider creating custom sparseMap encoding instead\n */\nexport type JsonFieldType = {\n type: \"json\"\n}\n\n/** Union of all available field types. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for field values\nexport type FieldType<TValue = any> =\n | BitArrayFieldType\n | IntArrayFieldType\n | IntFieldType\n | StringFieldType\n | StringArrayFieldType\n | SparseMapFieldType<TValue>\n | JsonFieldType\n\n/**\n * Function that migrates data from one version to another.\n *\n * **When to use:**\n *\n * - Add new fields with default values\n * - Transform existing field values\n * - Rename or restructure fields\n *\n * **Important:**\n *\n * - Migrations operate on decoded data objects, not strings\n * - Each migration goes from version N to version N+1\n * - Migrations are applied sequentially\n *\n * **Example:**\n *\n * ```typescript\n * migrations: {\n * 0: (oldData) => ({\n * ...oldData,\n * newField: 'default value'\n * }),\n * 1: (oldData) => ({\n * ...oldData,\n * name: oldData.name.toUpperCase()\n * })\n * }\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameters for migration input/output\nexport type DataMigration<TFrom = any, TTo = any> = (data: TFrom) => TTo\n\n/**\n * Map of version numbers to migration functions.\n *\n * Keys are the source version numbers (0, 1, 2, etc.)\n * Values are functions that migrate from that version to the next\n */\nexport type MigrationMap = {\n [fromVersion: number]: DataMigration\n}\n\n/**\n * Complete schema definition for encoding/decoding data.\n *\n * **Basic usage:**\n *\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * name: { type: \"string\" },\n * age: { type: \"int\" },\n * },\n * })\n * ```\n *\n * **With custom delimiter:**\n *\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * delimiter: '|', // Use | instead of :\n * fields: { ... }\n * })\n * ```\n *\n * **With migrations:**\n *\n * ```typescript\n * const schema = defineSchema({\n * version: 2,\n * fields: {\n * name: { type: \"string\" },\n * value: { type: \"int\" },\n * },\n * migrations: {\n * 0: (old) => ({ ...old, value: 0 }),\n * 1: (old) => ({ ...old, name: old.name.toUpperCase() }),\n * },\n * })\n * ```\n *\n * @param version - Current schema version (increment when making breaking changes)\n * @param delimiter - Character to separate fields (default: ':')\n * @param fields - Map of field names to field type definitions\n * @param migrations - Optional map of version migrations\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic type parameter for schema data, and field values need 'any' for flexibility\nexport type Schema<TData = any> = {\n version: number\n delimiter?: string\n fields: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Field values can be any type\n [K in keyof TData]: FieldType<any>\n }\n migrations?: MigrationMap\n}\n\n/**\n * Result of creating an encoder from a schema.\n *\n * **Usage:**\n *\n * ```typescript\n * const { encode, decode, migrate } = createEncoder(schema, context)\n *\n * // Encode data to string\n * const inputString = encode(data)\n *\n * // Decode string to data\n * const data = decode(inputString)\n *\n * // Migrate old version to current version\n * const currentVersion = migrate(oldInputString)\n * ```\n */\nexport type EncoderResult<TData> = {\n encode: (data: TData) => string\n decode: (str: string) => TData\n migrate: (str: string) => string\n}\n\n/**\n * Define a typed schema for encoding/decoding game state.\n *\n * **Purpose:**\n *\n * - Provides type inference for encode/decode functions\n * - Documents the structure of your input strings\n * - Enables version migrations\n *\n * **Example:**\n *\n * ```typescript\n * type GameData = {\n * revealed: boolean[]\n * score: number\n * annotations: Record<string, Annotation>\n * }\n *\n * export const schema = defineSchema<GameData>({\n * version: 1,\n * fields: {\n * revealed: { type: \"bitArray\" },\n * score: { type: \"int\" },\n * annotations: {\n * type: \"sparseMap\",\n * valueEncoder: (ann) => `${ann.level}.${ann.color}`,\n * valueDecoder: (str) => {\n * const [level, color] = str.split(\".\").map(Number)\n * return { level, color }\n * },\n * },\n * },\n * })\n * ```\n */\nexport function defineSchema<TData>(schema: Schema<TData>): Schema<TData> {\n return schema\n}\n","import type { Schema, EncoderResult } from \"./types\"\nimport { encode } from \"./encoder\"\nimport { decode } from \"./decoder\"\nimport { createMigrator } from \"./migration\"\n\nexport { defineSchema } from \"./types\"\nexport type {\n Schema,\n EncoderResult,\n FieldType,\n BitArrayFieldType,\n IntArrayFieldType,\n IntFieldType,\n StringFieldType,\n StringArrayFieldType,\n SparseMapFieldType,\n JsonFieldType,\n DataMigration,\n MigrationMap,\n} from \"./types\"\n\n/**\n * Create an encoder/decoder for a schema-defined data structure.\n *\n * **Basic usage:**\n *\n * ```typescript\n * import { defineSchema, createEncoder } from \"@puzzmo/sdk/inputs\"\n *\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * name: { type: \"string\" },\n * age: { type: \"int\" },\n * },\n * })\n *\n * const { encode, decode } = createEncoder(schema)\n *\n * const data = { name: \"Alice\", age: 30 }\n * const inputString = encode(data) // \"v1:Alice:30\"\n * const decoded = decode(inputString) // { name: 'Alice', age: 30 }\n * ```\n *\n * **With context (for length-dependent fields):**\n *\n * ```typescript\n * const schema = defineSchema({\n * version: 1,\n * fields: {\n * revealed: { type: \"bitArray\" },\n * scores: { type: \"intArray\" },\n * },\n * })\n *\n * const { encode, decode } = createEncoder(schema, {\n * revealed: { length: 100 }, // Required for bitArray decoding\n * scores: { length: 10 }, // Required for sparse intArray decoding\n * annotations: { keys: tileIds }, // Optional: optimize sparseMap with numeric indices\n * })\n * ```\n *\n * **With migrations:**\n *\n * ```typescript\n * const { encode, decode, migrate } = createEncoder(schema)\n *\n * const oldString = \"v0:Alice:30\"\n * const migrated = migrate(oldString) // \"v1:Alice:30:default\"\n * const data = decode(migrated)\n * ```\n *\n * @param schema - Schema definition created with defineSchema()\n * @param context - Optional context for decoding (lengths for bitArray/intArray)\n * @returns Object with encode, decode, and migrate functions\n */\nexport function createEncoder<TData>(\n schema: Schema<TData>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Context values can be any shape depending on field types\n context?: Record<string, any>,\n): EncoderResult<TData> {\n const migrator = createMigrator(schema)\n\n return {\n encode: (data: TData) => encode(schema, data, context),\n decode: (str: string) => decode(schema, str, context),\n migrate: (str: string) => migrator(str, context),\n }\n}\n"],"mappings":"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"}
|
package/dist/inputs/types.d.ts
CHANGED
|
@@ -2,15 +2,18 @@
|
|
|
2
2
|
* Encodes boolean arrays as compact hexadecimal strings.
|
|
3
3
|
*
|
|
4
4
|
* **When to use:**
|
|
5
|
+
*
|
|
5
6
|
* - Revealed/hidden state of game tiles
|
|
6
7
|
* - Feature flags or settings
|
|
7
8
|
* - Any boolean array where order matters
|
|
8
9
|
*
|
|
9
10
|
* **Encoding:**
|
|
11
|
+
*
|
|
10
12
|
* - Packs 4 bits per hex character (75% size reduction)
|
|
11
13
|
* - Example: [true, false, false, false, false, true, false, false] → "12"
|
|
12
14
|
*
|
|
13
15
|
* **Decoding:**
|
|
16
|
+
*
|
|
14
17
|
* - Requires length in context: `{ fieldName: { length: 100 } }`
|
|
15
18
|
*/
|
|
16
19
|
export type BitArrayFieldType = {
|
|
@@ -20,17 +23,20 @@ export type BitArrayFieldType = {
|
|
|
20
23
|
* Encodes integer arrays with automatic sparse optimization.
|
|
21
24
|
*
|
|
22
25
|
* **When to use:**
|
|
26
|
+
*
|
|
23
27
|
* - Arrays of numeric values (scores, counts, experience)
|
|
24
28
|
* - Sparse data (mostly zeros)
|
|
25
29
|
* - Dense data (will auto-fallback to CSV)
|
|
26
30
|
*
|
|
27
31
|
* **Encoding:**
|
|
32
|
+
*
|
|
28
33
|
* - Uses decimal (base-10) numbers separated by commas
|
|
29
34
|
* - Smart sparse: If >50% zeros, uses `index=value` pairs (e.g., "2=5,4=3")
|
|
30
35
|
* - Dense fallback: If not beneficial, uses CSV (e.g., "1,2,3,4")
|
|
31
36
|
* - Empty arrays encode as empty string
|
|
32
37
|
*
|
|
33
38
|
* **Decoding:**
|
|
39
|
+
*
|
|
34
40
|
* - Requires length in context for sparse format: `{ fieldName: { length: 100 } }`
|
|
35
41
|
* - CSV format decodes without context
|
|
36
42
|
*/
|
|
@@ -41,10 +47,12 @@ export type IntArrayFieldType = {
|
|
|
41
47
|
* Encodes single integer values.
|
|
42
48
|
*
|
|
43
49
|
* **When to use:**
|
|
50
|
+
*
|
|
44
51
|
* - Single numeric values (score, level, count)
|
|
45
52
|
* - Non-negative integers only
|
|
46
53
|
*
|
|
47
54
|
* **Encoding:**
|
|
55
|
+
*
|
|
48
56
|
* - Uses decimal (base-10) representation
|
|
49
57
|
* - Example: 42 → "42"
|
|
50
58
|
*/
|
|
@@ -55,10 +63,12 @@ export type IntFieldType = {
|
|
|
55
63
|
* Encodes string values as-is.
|
|
56
64
|
*
|
|
57
65
|
* **When to use:**
|
|
66
|
+
*
|
|
58
67
|
* - Single string values (name, color, mode)
|
|
59
68
|
* - Short identifiers
|
|
60
69
|
*
|
|
61
70
|
* **Warning:**
|
|
71
|
+
*
|
|
62
72
|
* - Strings containing the schema delimiter (default ':') will break parsing
|
|
63
73
|
* - Consider using a custom delimiter or different encoding for such strings
|
|
64
74
|
*/
|
|
@@ -69,14 +79,17 @@ export type StringFieldType = {
|
|
|
69
79
|
* Encodes arrays of strings.
|
|
70
80
|
*
|
|
71
81
|
* **When to use:**
|
|
82
|
+
*
|
|
72
83
|
* - Lists of tags, categories, or identifiers
|
|
73
84
|
* - Ordered collections of strings
|
|
74
85
|
*
|
|
75
86
|
* **Encoding:**
|
|
87
|
+
*
|
|
76
88
|
* - Uses comma delimiter by default
|
|
77
89
|
* - Custom delimiter can be specified to avoid conflicts
|
|
78
90
|
*
|
|
79
91
|
* **Warning:**
|
|
92
|
+
*
|
|
80
93
|
* - Strings containing the delimiter will break parsing
|
|
81
94
|
* - Use custom delimiter to avoid conflicts
|
|
82
95
|
*/
|
|
@@ -88,27 +101,31 @@ export type StringArrayFieldType = {
|
|
|
88
101
|
* Encodes sparse key-value maps with custom value encoding.
|
|
89
102
|
*
|
|
90
103
|
* **When to use:**
|
|
104
|
+
*
|
|
91
105
|
* - Tile annotations, cell metadata
|
|
92
106
|
* - Any sparse mapping where most keys don't have values
|
|
93
107
|
* - Custom object types that need specialized encoding
|
|
94
108
|
*
|
|
95
109
|
* **Encoding:**
|
|
110
|
+
*
|
|
96
111
|
* - With context keys: Uses numeric indices (e.g., `0=2.1,5=3.0`)
|
|
97
112
|
* - Without context: Uses string keys (e.g., `key1=val1;key2=val2`)
|
|
98
113
|
* - Only stores non-empty entries
|
|
99
114
|
* - Keys are always strings in the data, converted to indices when context provides ordered keys
|
|
100
|
-
* -
|
|
101
|
-
* -
|
|
115
|
+
* - ValueEncoder: Convert your object to a string
|
|
116
|
+
* - ValueDecoder: Parse string back to your object
|
|
102
117
|
*
|
|
103
118
|
* **Optimization:**
|
|
104
119
|
* Provide ordered keys in context to use numeric indices instead of string keys:
|
|
120
|
+
*
|
|
105
121
|
* ```typescript
|
|
106
122
|
* const { encode, decode } = createEncoder(schema, {
|
|
107
|
-
* annotations: { keys: tileIds }
|
|
123
|
+
* annotations: { keys: tileIds }, // Ordered list of possible keys
|
|
108
124
|
* })
|
|
109
125
|
* ```
|
|
110
126
|
*
|
|
111
127
|
* **Example:**
|
|
128
|
+
*
|
|
112
129
|
* ```typescript
|
|
113
130
|
* annotations: {
|
|
114
131
|
* type: 'sparseMap',
|
|
@@ -129,16 +146,19 @@ export type SparseMapFieldType<TValue = any> = {
|
|
|
129
146
|
* Encodes arbitrary data as JSON with automatic compression.
|
|
130
147
|
*
|
|
131
148
|
* **When to use:**
|
|
149
|
+
*
|
|
132
150
|
* - Complex nested structures
|
|
133
151
|
* - Fallback for data that doesn't fit other types
|
|
134
152
|
* - Temporary solution before implementing custom encoding
|
|
135
153
|
*
|
|
136
154
|
* **Encoding:**
|
|
155
|
+
*
|
|
137
156
|
* - Converts data to JSON string
|
|
138
157
|
* - Automatically compresses with lz-string
|
|
139
158
|
* - Helps reduce size of complex objects
|
|
140
159
|
*
|
|
141
160
|
* **Warning:**
|
|
161
|
+
*
|
|
142
162
|
* - Still larger than specialized encodings even with compression
|
|
143
163
|
* - Use only when necessary
|
|
144
164
|
* - Consider creating custom sparseMap encoding instead
|
|
@@ -146,24 +166,25 @@ export type SparseMapFieldType<TValue = any> = {
|
|
|
146
166
|
export type JsonFieldType = {
|
|
147
167
|
type: "json";
|
|
148
168
|
};
|
|
149
|
-
/**
|
|
150
|
-
* Union of all available field types.
|
|
151
|
-
*/
|
|
169
|
+
/** Union of all available field types. */
|
|
152
170
|
export type FieldType<TValue = any> = BitArrayFieldType | IntArrayFieldType | IntFieldType | StringFieldType | StringArrayFieldType | SparseMapFieldType<TValue> | JsonFieldType;
|
|
153
171
|
/**
|
|
154
172
|
* Function that migrates data from one version to another.
|
|
155
173
|
*
|
|
156
174
|
* **When to use:**
|
|
175
|
+
*
|
|
157
176
|
* - Add new fields with default values
|
|
158
177
|
* - Transform existing field values
|
|
159
178
|
* - Rename or restructure fields
|
|
160
179
|
*
|
|
161
180
|
* **Important:**
|
|
181
|
+
*
|
|
162
182
|
* - Migrations operate on decoded data objects, not strings
|
|
163
183
|
* - Each migration goes from version N to version N+1
|
|
164
184
|
* - Migrations are applied sequentially
|
|
165
185
|
*
|
|
166
186
|
* **Example:**
|
|
187
|
+
*
|
|
167
188
|
* ```typescript
|
|
168
189
|
* migrations: {
|
|
169
190
|
* 0: (oldData) => ({
|
|
@@ -191,17 +212,19 @@ export type MigrationMap = {
|
|
|
191
212
|
* Complete schema definition for encoding/decoding data.
|
|
192
213
|
*
|
|
193
214
|
* **Basic usage:**
|
|
215
|
+
*
|
|
194
216
|
* ```typescript
|
|
195
217
|
* const schema = defineSchema({
|
|
196
218
|
* version: 1,
|
|
197
219
|
* fields: {
|
|
198
|
-
* name: { type:
|
|
199
|
-
* age: { type:
|
|
200
|
-
* }
|
|
220
|
+
* name: { type: "string" },
|
|
221
|
+
* age: { type: "int" },
|
|
222
|
+
* },
|
|
201
223
|
* })
|
|
202
224
|
* ```
|
|
203
225
|
*
|
|
204
226
|
* **With custom delimiter:**
|
|
227
|
+
*
|
|
205
228
|
* ```typescript
|
|
206
229
|
* const schema = defineSchema({
|
|
207
230
|
* version: 1,
|
|
@@ -211,17 +234,18 @@ export type MigrationMap = {
|
|
|
211
234
|
* ```
|
|
212
235
|
*
|
|
213
236
|
* **With migrations:**
|
|
237
|
+
*
|
|
214
238
|
* ```typescript
|
|
215
239
|
* const schema = defineSchema({
|
|
216
240
|
* version: 2,
|
|
217
241
|
* fields: {
|
|
218
|
-
* name: { type:
|
|
219
|
-
* value: { type:
|
|
242
|
+
* name: { type: "string" },
|
|
243
|
+
* value: { type: "int" },
|
|
220
244
|
* },
|
|
221
245
|
* migrations: {
|
|
222
246
|
* 0: (old) => ({ ...old, value: 0 }),
|
|
223
|
-
* 1: (old) => ({ ...old, name: old.name.toUpperCase() })
|
|
224
|
-
* }
|
|
247
|
+
* 1: (old) => ({ ...old, name: old.name.toUpperCase() }),
|
|
248
|
+
* },
|
|
225
249
|
* })
|
|
226
250
|
* ```
|
|
227
251
|
*
|
|
@@ -242,6 +266,7 @@ export type Schema<TData = any> = {
|
|
|
242
266
|
* Result of creating an encoder from a schema.
|
|
243
267
|
*
|
|
244
268
|
* **Usage:**
|
|
269
|
+
*
|
|
245
270
|
* ```typescript
|
|
246
271
|
* const { encode, decode, migrate } = createEncoder(schema, context)
|
|
247
272
|
*
|
|
@@ -264,11 +289,13 @@ export type EncoderResult<TData> = {
|
|
|
264
289
|
* Define a typed schema for encoding/decoding game state.
|
|
265
290
|
*
|
|
266
291
|
* **Purpose:**
|
|
292
|
+
*
|
|
267
293
|
* - Provides type inference for encode/decode functions
|
|
268
294
|
* - Documents the structure of your input strings
|
|
269
295
|
* - Enables version migrations
|
|
270
296
|
*
|
|
271
297
|
* **Example:**
|
|
298
|
+
*
|
|
272
299
|
* ```typescript
|
|
273
300
|
* type GameData = {
|
|
274
301
|
* revealed: boolean[]
|
|
@@ -279,17 +306,17 @@ export type EncoderResult<TData> = {
|
|
|
279
306
|
* export const schema = defineSchema<GameData>({
|
|
280
307
|
* version: 1,
|
|
281
308
|
* fields: {
|
|
282
|
-
* revealed: { type:
|
|
283
|
-
* score: { type:
|
|
309
|
+
* revealed: { type: "bitArray" },
|
|
310
|
+
* score: { type: "int" },
|
|
284
311
|
* annotations: {
|
|
285
|
-
* type:
|
|
312
|
+
* type: "sparseMap",
|
|
286
313
|
* valueEncoder: (ann) => `${ann.level}.${ann.color}`,
|
|
287
314
|
* valueDecoder: (str) => {
|
|
288
|
-
* const [level, color] = str.split(
|
|
315
|
+
* const [level, color] = str.split(".").map(Number)
|
|
289
316
|
* return { level, color }
|
|
290
|
-
* }
|
|
291
|
-
* }
|
|
292
|
-
* }
|
|
317
|
+
* },
|
|
318
|
+
* },
|
|
319
|
+
* },
|
|
293
320
|
* })
|
|
294
321
|
* ```
|
|
295
322
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/inputs/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/inputs/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,UAAU,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,UAAU,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,KAAK,CAAA;CACZ,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,QAAQ,CAAA;CACf,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,aAAa,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,MAAM,MAAM,kBAAkB,CAAC,MAAM,GAAG,GAAG,IAAI;IAC7C,IAAI,EAAE,WAAW,CAAA;IACjB,YAAY,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACvC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CACtC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,0CAA0C;AAE1C,MAAM,MAAM,SAAS,CAAC,MAAM,GAAG,GAAG,IAC9B,iBAAiB,GACjB,iBAAiB,GACjB,YAAY,GACZ,eAAe,GACf,oBAAoB,GACpB,kBAAkB,CAAC,MAAM,CAAC,GAC1B,aAAa,CAAA;AAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,MAAM,aAAa,CAAC,KAAK,GAAG,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,KAAK,GAAG,CAAA;AAExE;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAAA;CACrC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AAEH,MAAM,MAAM,MAAM,CAAC,KAAK,GAAG,GAAG,IAAI;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE;SAEL,CAAC,IAAI,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC;KACnC,CAAA;IACD,UAAU,CAAC,EAAE,YAAY,CAAA;CAC1B,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,aAAa,CAAC,KAAK,IAAI;IACjC,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,CAAA;IAC/B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,KAAK,CAAA;IAC9B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAA;CACjC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAExE"}
|
package/dist/keyboard.d.ts
CHANGED
|
@@ -4,12 +4,12 @@ import type { KeyboardConfig } from "./types";
|
|
|
4
4
|
* any game that needs text input. Customize from here by spreading and overriding.
|
|
5
5
|
*
|
|
6
6
|
* @example
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* // Use as-is
|
|
8
|
+
* sdk.keyboard.show(defaultKeyboardConfig)
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* // Extend with dynamic disabled letters
|
|
12
|
+
* sdk.keyboard.show({ ...defaultKeyboardConfig, disabled: usedLetters })
|
|
13
13
|
*/
|
|
14
14
|
export declare const defaultKeyboardConfig: KeyboardConfig;
|
|
15
15
|
//# sourceMappingURL=keyboard.d.ts.map
|
|
@@ -9,6 +9,7 @@ interface SimulatorInstance {
|
|
|
9
9
|
* Simulator - A development UI for testing games with the Puzzmo Proto SDK.
|
|
10
10
|
*
|
|
11
11
|
* This script simulates the Puzzmo host environment by:
|
|
12
|
+
*
|
|
12
13
|
* - Listening for READY messages from the game
|
|
13
14
|
* - Sending READY_DATA with puzzle data
|
|
14
15
|
* - Providing UI controls for START_GAME, PAUSE_GAME, RESUME_GAME, RETRY_PUZZLE
|
|
@@ -19,7 +20,7 @@ interface SimulatorInstance {
|
|
|
19
20
|
* // vite.config.ts
|
|
20
21
|
* import { puzzmoSimulator } from "@puzzmo/sdk/vite"
|
|
21
22
|
* export default defineConfig({
|
|
22
|
-
* plugins: [puzzmoSimulator({})]
|
|
23
|
+
* plugins: [puzzmoSimulator({})],
|
|
23
24
|
* })
|
|
24
25
|
* ```
|
|
25
26
|
*
|
|
@@ -28,6 +29,7 @@ interface SimulatorInstance {
|
|
|
28
29
|
* The plugin handles making sure it is removed on vite builds.
|
|
29
30
|
*
|
|
30
31
|
* Usage with manual imports:
|
|
32
|
+
*
|
|
31
33
|
* ```html
|
|
32
34
|
* <script type="module">
|
|
33
35
|
* import { createSimulator } from "@puzzmo/sdk/simulator"
|
|
@@ -35,6 +37,7 @@ interface SimulatorInstance {
|
|
|
35
37
|
* createSimulator({ fixtures })
|
|
36
38
|
* </script>
|
|
37
39
|
* ```
|
|
40
|
+
*
|
|
38
41
|
* The fixtures folder structure should be: fixtures/puzzles/{category}/{puzzle}.json
|
|
39
42
|
* This will show dropdowns in the Ctrl tab to select category and puzzle.
|
|
40
43
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createSimulator.d.ts","sourceRoot":"","sources":["../../src/simulator/createSimulator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAA4D,cAAc,EAAE,MAAM,SAAS,CAAA;AAmBxH,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA;AAG/C,UAAU,iBAAiB;IACzB,cAAc,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAA;IAClD,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;CAC/B;AAGD
|
|
1
|
+
{"version":3,"file":"createSimulator.d.ts","sourceRoot":"","sources":["../../src/simulator/createSimulator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAA4D,cAAc,EAAE,MAAM,SAAS,CAAA;AAmBxH,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,CAAA;AAG/C,UAAU,iBAAiB;IACzB,cAAc,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,CAAA;IAClD,UAAU,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;IAC1C,UAAU,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAA;CAC/B;AAGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,wBAAgB,eAAe,CAAC,MAAM,GAAE,eAAoB,GAAG,iBAAiB,CAugB/E"}
|
|
@@ -1,18 +1,10 @@
|
|
|
1
1
|
import type { FixtureImports } from "./types";
|
|
2
|
-
/**
|
|
3
|
-
* Parse fixture imports into a structured format: { category: { filename: data } }
|
|
4
|
-
*/
|
|
2
|
+
/** Parse fixture imports into a structured format: { category: { filename: data } } */
|
|
5
3
|
export declare function parseFixtures(fixtures: FixtureImports): Map<string, Map<string, any>>;
|
|
6
|
-
/**
|
|
7
|
-
* Render fixture selector HTML
|
|
8
|
-
*/
|
|
4
|
+
/** Render fixture selector HTML */
|
|
9
5
|
export declare function renderFixtureSelector(categories: string[], selectedCategory: string | null): string;
|
|
10
|
-
/**
|
|
11
|
-
* Update puzzle select options based on selected category
|
|
12
|
-
*/
|
|
6
|
+
/** Update puzzle select options based on selected category */
|
|
13
7
|
export declare function updatePuzzleOptions(puzzleSelect: HTMLSelectElement, fixtures: Map<string, Map<string, any>>, category: string, selectedPuzzle: string | null): string | null;
|
|
14
|
-
/**
|
|
15
|
-
* Get puzzle data from fixtures
|
|
16
|
-
*/
|
|
8
|
+
/** Get puzzle data from fixtures */
|
|
17
9
|
export declare function getFixturePuzzle(fixtures: Map<string, Map<string, any>>, category: string | null, puzzle: string | null): any | null;
|
|
18
10
|
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/simulator/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/simulator/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAgCrF;AAED,mCAAmC;AACnC,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAiBnG;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,iBAAiB,EAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EACvC,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,GAAG,IAAI,GAC5B,MAAM,GAAG,IAAI,CAiBf;AAED,oCAAoC;AACpC,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAGpI"}
|
package/dist/simulator/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../createSimulator-
|
|
1
|
+
import { t as e } from "../createSimulator-jeSc_X3r.js";
|
|
2
2
|
export { e as createSimulator };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.cjs","names":[],"sources":["../../src/simulator/standalone.ts"],"sourcesContent":["/**\n * Standalone entry point for the simulator.\n *\n * Use as a script tag for non-Vite setups:\n * ```html\n * <script>\n * window.SIMULATOR_CONFIG = { slug: \"my-game\" }\n * </script>\n * <script src=\"https://cdn.jsdelivr.net/npm/@puzzmo/sdk/dist/simulator/standalone.js\"></script>\n * ```\n */\nimport { createSimulator } from \"./createSimulator\"\nimport type { SimulatorConfig } from \"./types\"\n\ndeclare global {\n interface Window {\n SIMULATOR_CONFIG?: SimulatorConfig\n }\n}\n\nconst init = () => {\n const config = window.SIMULATOR_CONFIG ?? {}\n createSimulator(config)\n}\n\nif (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init)\n} else {\n init()\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"standalone.cjs","names":[],"sources":["../../src/simulator/standalone.ts"],"sourcesContent":["/**\n * Standalone entry point for the simulator.\n *\n * Use as a script tag for non-Vite setups:\n *\n * ```html\n * <script>\n * window.SIMULATOR_CONFIG = { slug: \"my-game\" }\n * </script>\n * <script src=\"https://cdn.jsdelivr.net/npm/@puzzmo/sdk/dist/simulator/standalone.js\"></script>\n * ```\n */\nimport { createSimulator } from \"./createSimulator\"\nimport type { SimulatorConfig } from \"./types\"\n\ndeclare global {\n interface Window {\n SIMULATOR_CONFIG?: SimulatorConfig\n }\n}\n\nconst init = () => {\n const config = window.SIMULATOR_CONFIG ?? {}\n createSimulator(config)\n}\n\nif (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init)\n} else {\n init()\n}\n"],"mappings":"mDAqBA,IAAM,MAAa,OAEjB,EAAA,GAAA,EADe,OAAO,mBAAA,KAAoB,EAAE,CAAtB,EACC,EAGrB,SAAS,aAAe,UAC1B,SAAS,iBAAiB,mBAAoB,EAAK,CAEnD,GAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../src/simulator/standalone.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"standalone.d.ts","sourceRoot":"","sources":["../../src/simulator/standalone.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,CAAC,MAAM,CAAC,CAAC;IACd,UAAU,MAAM;QACd,gBAAgB,CAAC,EAAE,eAAe,CAAA;KACnC;CACF"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { t as e } from "../createSimulator-
|
|
1
|
+
import { t as e } from "../createSimulator-jeSc_X3r.js";
|
|
2
2
|
/**
|
|
3
3
|
* Standalone entry point for the simulator.
|
|
4
4
|
*
|
|
5
5
|
* Use as a script tag for non-Vite setups:
|
|
6
|
+
*
|
|
6
7
|
* ```html
|
|
7
8
|
* <script>
|
|
8
9
|
* window.SIMULATOR_CONFIG = { slug: "my-game" }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"standalone.js","names":[],"sources":["../../src/simulator/standalone.ts"],"sourcesContent":["/**\n * Standalone entry point for the simulator.\n *\n * Use as a script tag for non-Vite setups:\n * ```html\n * <script>\n * window.SIMULATOR_CONFIG = { slug: \"my-game\" }\n * </script>\n * <script src=\"https://cdn.jsdelivr.net/npm/@puzzmo/sdk/dist/simulator/standalone.js\"></script>\n * ```\n */\nimport { createSimulator } from \"./createSimulator\"\nimport type { SimulatorConfig } from \"./types\"\n\ndeclare global {\n interface Window {\n SIMULATOR_CONFIG?: SimulatorConfig\n }\n}\n\nconst init = () => {\n const config = window.SIMULATOR_CONFIG ?? {}\n createSimulator(config)\n}\n\nif (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init)\n} else {\n init()\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"file":"standalone.js","names":[],"sources":["../../src/simulator/standalone.ts"],"sourcesContent":["/**\n * Standalone entry point for the simulator.\n *\n * Use as a script tag for non-Vite setups:\n *\n * ```html\n * <script>\n * window.SIMULATOR_CONFIG = { slug: \"my-game\" }\n * </script>\n * <script src=\"https://cdn.jsdelivr.net/npm/@puzzmo/sdk/dist/simulator/standalone.js\"></script>\n * ```\n */\nimport { createSimulator } from \"./createSimulator\"\nimport type { SimulatorConfig } from \"./types\"\n\ndeclare global {\n interface Window {\n SIMULATOR_CONFIG?: SimulatorConfig\n }\n}\n\nconst init = () => {\n const config = window.SIMULATOR_CONFIG ?? {}\n createSimulator(config)\n}\n\nif (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init)\n} else {\n init()\n}\n"],"mappings":";;;;;;;;;;;;;AAqBA,IAAM,UAAa;;AAEjB,IAAA,IADe,OAAO,qBAAA,OAAoB,EAAE,GAAtB,EACC;;AAGrB,SAAS,eAAe,YAC1B,SAAS,iBAAiB,oBAAoB,EAAK,GAEnD,GAAM"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/DataView.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"DataView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/DataView.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAoB,aAAa,EAAE,MAAM,UAAU,CAAA;AAiE/D,wBAAgB,cAAc,IAAI,aAAa,CAsQ9C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/ThemeView.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"ThemeView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/ThemeView.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAoB,aAAa,EAAE,MAAM,UAAU,CAAA;AAW/D,wBAAgB,eAAe,IAAI,aAAa,CAqC/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThumbView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/ThumbView.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"ThumbView.d.ts","sourceRoot":"","sources":["../../../src/simulator/views/ThumbView.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAc/D,MAAM,WAAW,iBAAkB,SAAQ,aAAa;IACtD,aAAa,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC/C;AAED,wBAAgB,eAAe,IAAI,iBAAiB,CAkInD"}
|