@puzzmo/sdk 0.0.2 → 0.0.4

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/README.md CHANGED
@@ -27,19 +27,19 @@ pnpm add @puzzmo/sdk
27
27
  ### ES Modules (Node.js, Bundlers)
28
28
 
29
29
  ```javascript
30
- import { helloWorld, getVersion } from '@puzzmo/sdk'
30
+ import { helloWorld, getVersion } from "@puzzmo/sdk"
31
31
 
32
32
  console.log(helloWorld()) // "Hello from Puzzmo SDK!"
33
- console.log(getVersion()) // "0.0.1"
33
+ console.log(getVersion()) // "0.0.1"
34
34
  ```
35
35
 
36
36
  ### CommonJS (Node.js)
37
37
 
38
38
  ```javascript
39
- const { helloWorld, getVersion } = require('@puzzmo/sdk')
39
+ const { helloWorld, getVersion } = require("@puzzmo/sdk")
40
40
 
41
41
  console.log(helloWorld()) // "Hello from Puzzmo SDK!"
42
- console.log(getVersion()) // "0.0.1"
42
+ console.log(getVersion()) // "0.0.1"
43
43
  ```
44
44
 
45
45
  ### UMD (Browser via CDN)
@@ -47,15 +47,15 @@ console.log(getVersion()) // "0.0.1"
47
47
  ```html
48
48
  <!DOCTYPE html>
49
49
  <html>
50
- <head>
51
- <script src="https://unpkg.com/@puzzmo/sdk@latest/dist/index.umd.js"></script>
52
- </head>
53
- <body>
54
- <script>
55
- console.log(PuzzmoSDK.helloWorld()) // "Hello from Puzzmo SDK!"
56
- console.log(PuzzmoSDK.getVersion()) // "0.0.1"
57
- </script>
58
- </body>
50
+ <head>
51
+ <script src="https://unpkg.com/@puzzmo/sdk@latest/dist/index.umd.js"></script>
52
+ </head>
53
+ <body>
54
+ <script>
55
+ console.log(PuzzmoSDK.helloWorld()) // "Hello from Puzzmo SDK!"
56
+ console.log(PuzzmoSDK.getVersion()) // "0.0.1"
57
+ </script>
58
+ </body>
59
59
  </html>
60
60
  ```
61
61
 
@@ -78,15 +78,15 @@ IIFE (Immediately Invoked Function Expression) is a more compact format ideal fo
78
78
  ```html
79
79
  <!DOCTYPE html>
80
80
  <html>
81
- <head>
82
- <script src="https://unpkg.com/@puzzmo/sdk@latest/dist/index.iife.js"></script>
83
- </head>
84
- <body>
85
- <script>
86
- console.log(PuzzmoSDK.helloWorld()) // "Hello from Puzzmo SDK!"
87
- console.log(PuzzmoSDK.getVersion()) // "0.0.1"
88
- </script>
89
- </body>
81
+ <head>
82
+ <script src="https://unpkg.com/@puzzmo/sdk@latest/dist/index.iife.js"></script>
83
+ </head>
84
+ <body>
85
+ <script>
86
+ console.log(PuzzmoSDK.helloWorld()) // "Hello from Puzzmo SDK!"
87
+ console.log(PuzzmoSDK.getVersion()) // "0.0.1"
88
+ </script>
89
+ </body>
90
90
  </html>
91
91
  ```
92
92
 
@@ -99,8 +99,9 @@ Returns a hello world message from the Puzzmo SDK.
99
99
  **Returns:** `string` - A greeting message
100
100
 
101
101
  **Example:**
102
+
102
103
  ```javascript
103
- import { helloWorld } from '@puzzmo/sdk'
104
+ import { helloWorld } from "@puzzmo/sdk"
104
105
 
105
106
  const message = helloWorld()
106
107
  console.log(message) // "Hello from Puzzmo SDK!"
@@ -113,8 +114,9 @@ Returns the current SDK version.
113
114
  **Returns:** `string` - The SDK version
114
115
 
115
116
  **Example:**
117
+
116
118
  ```javascript
117
- import { getVersion } from '@puzzmo/sdk'
119
+ import { getVersion } from "@puzzmo/sdk"
118
120
 
119
121
  const version = getVersion()
120
122
  console.log(version) // "0.0.1"
@@ -131,6 +133,12 @@ yarn install
131
133
  # Build the SDK
132
134
  yarn workspace @puzzmo/sdk build
133
135
 
136
+ # Generate SDK types from hostAPI.d.ts
137
+ yarn workspace @puzzmo/sdk generate-sdk
138
+
139
+ # Watch mode for SDK type generation (auto-regenerates on changes)
140
+ yarn workspace @puzzmo/sdk generate-sdk:watch
141
+
134
142
  # Run tests
135
143
  yarn workspace @puzzmo/sdk test
136
144
 
@@ -146,7 +154,10 @@ yarn workspace @puzzmo/sdk type-check
146
154
  ```
147
155
  packages/sdk/
148
156
  ├── src/
149
- └── index.ts # Main SDK source
157
+ ├── index.ts # Main SDK source
158
+ │ └── puzzmoSDK.d.ts # Auto-generated types (DO NOT EDIT)
159
+ ├── scripts/
160
+ │ └── generateSDK.ts # Type generation script
150
161
  ├── dist/ # Build output (generated)
151
162
  │ ├── index.js # ES module build
152
163
  │ ├── index.cjs # CommonJS build
@@ -159,6 +170,20 @@ packages/sdk/
159
170
  └── README.md
160
171
  ```
161
172
 
173
+ ### Type Generation
174
+
175
+ The SDK types in `puzzmoSDK.d.ts` are automatically generated from multiple sources:
176
+
177
+ 1. **`@puzzmo-com/shared/hostAPI.d.ts`**: Types marked with `@public` JSDoc tags
178
+ 2. **`@puzzmo-com/keyboard/src/types.ts`**: Explicitly included types (e.g., `KeyboardConfig`)
179
+
180
+ The generation script processes both files and combines them into a single SDK type file. To add new types:
181
+
182
+ - For types from `hostAPI.d.ts`: Add `@public` JSDoc tag
183
+ - For types from `keyboard/types.ts`: Add the type name to the `includeTypes` array in `generateSDK.ts`
184
+
185
+ **DO NOT edit `puzzmoSDK.d.ts` directly** - it will be overwritten on every build.
186
+
162
187
  ### Build Outputs
163
188
 
164
189
  The SDK provides multiple build outputs to support different environments:
@@ -186,11 +211,13 @@ See [PUBLISHING.md](./PUBLISHING.md) for complete setup instructions and securit
186
211
  ### Quick Start: Publishing a New Version
187
212
 
188
213
  1. Update the version in `packages/sdk/package.json`:
214
+
189
215
  ```bash
190
216
  npm version patch # or minor/major
191
217
  ```
192
218
 
193
219
  2. Commit and push to `main`:
220
+
194
221
  ```bash
195
222
  git add package.json
196
223
  git commit -m "chore(sdk): bump version to x.x.x"
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function e(){return"Hello from Puzzmo SDK!"}function o(){return"0.0.1"}exports.getVersion=o;exports.helloWorld=e;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class s extends Error{constructor(o,e,t){super(e),this.type=o,this.originalError=t,this.name="WorkshopImportError"}}function l(r){return{hello:()=>{console.log("Hello from Puzzmo SDK!",r)}}}exports.WorkshopImportError=s;exports.createPuzzmoSDK=l;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["/**\n * Puzzmo SDK\n * Provides runtime and API access for Puzzmo games\n */\n\n/**\n * Returns a hello world message from the Puzzmo SDK\n * @returns A greeting message\n */\nexport function helloWorld(): string {\n return \"Hello from Puzzmo SDK!\"\n}\n\n/**\n * Returns the SDK version\n * @returns The current SDK version\n */\nexport function getVersion(): string {\n return \"0.0.1\"\n}\n"],"names":["helloWorld","getVersion"],"mappings":"gFASO,SAASA,GAAqB,CACnC,MAAO,wBACT,CAMO,SAASC,GAAqB,CACnC,MAAO,OACT"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/workshop.ts","../src/index.ts"],"sourcesContent":["/**\n * Severity level for validation issues.\n *\n * - `error`: Critical issue that prevents puzzle from being valid\n * - `warning`: Issue that should be addressed but doesn't prevent usage\n * - `info`: Informational message about the puzzle\n */\nexport type ValidationLevel = \"error\" | \"warning\" | \"info\";\n\n/** Represents a single validation issue found during puzzle validation. */\nexport interface ValidationIssue {\n /** Severity level of this validation issue */\n level: ValidationLevel;\n /** Human-readable description of the issue */\n message: string;\n /** Line number in the puzzle data where the issue occurs (1-indexed, optional) */\n line?: number;\n /**\n * Column position in the puzzle data where the issue occurs (1-indexed,\n * optional)\n */\n col?: number;\n /** Length of the problematic text segment for highlighting (optional) */\n length?: number;\n}\n\n/**\n * Complete validation report for a puzzle. Contains the overall validation\n * status and any issues found.\n */\nexport interface ValidationReport {\n /** Whether the puzzle passed validation without errors */\n success: boolean;\n /** Array of validation issues found (errors, warnings, and info messages) */\n issues: ValidationIssue[];\n}\n\n/**\n * Types of errors that can occur during puzzle import.\n *\n * - `invalid_format`: The file format is not supported or recognized\n * - `parsing_error`: The file format is valid but parsing failed\n * - `unknown`: An unexpected error occurred during import\n */\nexport type ImportErrorType = \"invalid_format\" | \"parsing_error\" | \"unknown\";\n\n/**\n * Custom error class for workshop import failures. Thrown by the `onImport`\n * function when a puzzle cannot be imported.\n *\n * @example\n *\n * ```typescript\n * throw new WorkshopImportError(\n * \"invalid_format\",\n * \"Unsupported file extension: .xyz\",\n * );\n * ```\n */\nexport class WorkshopImportError extends Error {\n constructor(\n /** The category of import error */\n public type: ImportErrorType,\n /** Human-readable error message */\n message: string,\n /** Optional underlying error that caused the import to fail */\n public originalError?: unknown,\n ) {\n super(message);\n this.name = \"WorkshopImportError\";\n }\n}\n\n/**\n * Result of a successful puzzle import operation. Contains the converted puzzle\n * data and optional metadata.\n */\nexport interface ImportResult {\n /**\n * The converted puzzle data in the target format (e.g., XD format for\n * crosswords)\n */\n data: string;\n /** Optional validation warnings about the imported puzzle */\n warnings?: ValidationIssue[];\n /** Optional puzzle title extracted from the import file */\n title?: string;\n /** Optional list of puzzle authors */\n authors?: string[];\n /** Optional list of puzzle editors */\n editors?: string[];\n}\n\n/**\n * Main interface for a Workshop bundle. Workshop bundles are dynamically loaded\n * modules that provide game-specific functionality for puzzle validation and\n * import.\n *\n * @example\n *\n * ```typescript\n * // In your workshop bundle (e.g., games/crossword/src/workshop/index.ts)\n * export const validator = {\n * validate(data: string): ValidationReport {\n * // Custom validation logic\n * return { success: true, issues: [] };\n * },\n * };\n *\n * export const importer = {\n * async onImport(\n * filename: string,\n * contents: string | ArrayBuffer,\n * ): Promise<ImportResult> {\n * // Custom import logic\n * return { data: convertedData };\n * },\n * };\n * ```\n */\nexport interface WorkshopBundle {\n /** Required validator for puzzle data validation */\n validator: {\n /**\n * Validates puzzle data and returns a report of issues.\n *\n * @param data - The raw puzzle data string to validate\n *\n * @returns Validation report with success status and any issues found\n */\n validate(data: string): Promise<ValidationReport> | ValidationReport;\n };\n /** Optional importer for converting external puzzle file formats */\n importer?: {\n /**\n * Imports a puzzle file and converts it to the game's native format. Should\n * throw `WorkshopImportError` for known failure cases.\n *\n * @param filename - Name of the file being imported\n * @param contents - Raw file contents (string for\n * text files, ArrayBuffer for binary)\n *\n * @returns Import result with converted data and optional metadata\n *\n * @throws {WorkshopImportError} For invalid or unsupported files\n */\n onImport(\n filename: string,\n contents: string | ArrayBuffer,\n ): Promise<ImportResult> | ImportResult;\n };\n}\n","import { GameConfig } from \"./puzzmoSDK\";\n\n// Export the auto-generated public SDK types\nexport type * from \"./puzzmoSDK\";\n\n// Export workshop types\nexport * from \"./workshop\";\n\n/**\n * Creates a Puzzmo SDK instance\n *\n * @param config - Configuration options\n *\n * @returns A Puzzmo SDK instance\n */\nexport function createPuzzmoSDK(config: GameConfig) {\n return {\n hello: () => {\n console.log(\"Hello from Puzzmo SDK!\", config);\n },\n };\n}\n\nexport type PuzzmoSDK = ReturnType<typeof createPuzzmoSDK>;\n"],"names":["WorkshopImportError","type","message","originalError","createPuzzmoSDK","config"],"mappings":"gFA2DO,MAAMA,UAA4B,KAAM,CAC7C,YAESC,EAEPC,EAEOC,EACP,CACA,MAAMD,CAAO,EANN,KAAA,KAAAD,EAIA,KAAA,cAAAE,EAGP,KAAK,KAAO,qBACd,CACF,CCxDO,SAASC,EAAgBC,EAAoB,CAClD,MAAO,CACL,MAAO,IAAM,CACX,QAAQ,IAAI,yBAA0BA,CAAM,CAC9C,CAAA,CAEJ"}
package/dist/index.d.ts CHANGED
@@ -1,15 +1,15 @@
1
+ import { GameConfig } from "./puzzmoSDK";
2
+ export type * from "./puzzmoSDK";
3
+ export * from "./workshop";
1
4
  /**
2
- * Puzzmo SDK
3
- * Provides runtime and API access for Puzzmo games
5
+ * Creates a Puzzmo SDK instance
6
+ *
7
+ * @param config - Configuration options
8
+ *
9
+ * @returns A Puzzmo SDK instance
4
10
  */
5
- /**
6
- * Returns a hello world message from the Puzzmo SDK
7
- * @returns A greeting message
8
- */
9
- export declare function helloWorld(): string;
10
- /**
11
- * Returns the SDK version
12
- * @returns The current SDK version
13
- */
14
- export declare function getVersion(): string;
11
+ export declare function createPuzzmoSDK(config: GameConfig): {
12
+ hello: () => void;
13
+ };
14
+ export type PuzzmoSDK = ReturnType<typeof createPuzzmoSDK>;
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,mBAAmB,aAAa,CAAC;AAGjC,cAAc,YAAY,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU;;EAMjD;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC"}
@@ -1,2 +1,2 @@
1
- var PuzzmoSDK=function(e){"use strict";function o(){return"Hello from Puzzmo SDK!"}function n(){return"0.0.1"}return e.getVersion=n,e.helloWorld=o,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),e}({});
1
+ var PuzzmoSDK=(function(r){"use strict";class t extends Error{constructor(n,u,l){super(u),this.type=n,this.originalError=l,this.name="WorkshopImportError"}}function e(o){return{hello:()=>{console.log("Hello from Puzzmo SDK!",o)}}}return r.WorkshopImportError=t,r.createPuzzmoSDK=e,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"}),r})({});
2
2
  //# sourceMappingURL=index.iife.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.iife.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Puzzmo SDK\n * Provides runtime and API access for Puzzmo games\n */\n\n/**\n * Returns a hello world message from the Puzzmo SDK\n * @returns A greeting message\n */\nexport function helloWorld(): string {\n return \"Hello from Puzzmo SDK!\"\n}\n\n/**\n * Returns the SDK version\n * @returns The current SDK version\n */\nexport function getVersion(): string {\n return \"0.0.1\"\n}\n"],"names":["helloWorld","getVersion"],"mappings":"uCASO,SAASA,GAAqB,CACnC,MAAO,wBACT,CAMO,SAASC,GAAqB,CACnC,MAAO,OACT"}
1
+ {"version":3,"file":"index.iife.js","sources":["../src/workshop.ts","../src/index.ts"],"sourcesContent":["/**\n * Severity level for validation issues.\n *\n * - `error`: Critical issue that prevents puzzle from being valid\n * - `warning`: Issue that should be addressed but doesn't prevent usage\n * - `info`: Informational message about the puzzle\n */\nexport type ValidationLevel = \"error\" | \"warning\" | \"info\";\n\n/** Represents a single validation issue found during puzzle validation. */\nexport interface ValidationIssue {\n /** Severity level of this validation issue */\n level: ValidationLevel;\n /** Human-readable description of the issue */\n message: string;\n /** Line number in the puzzle data where the issue occurs (1-indexed, optional) */\n line?: number;\n /**\n * Column position in the puzzle data where the issue occurs (1-indexed,\n * optional)\n */\n col?: number;\n /** Length of the problematic text segment for highlighting (optional) */\n length?: number;\n}\n\n/**\n * Complete validation report for a puzzle. Contains the overall validation\n * status and any issues found.\n */\nexport interface ValidationReport {\n /** Whether the puzzle passed validation without errors */\n success: boolean;\n /** Array of validation issues found (errors, warnings, and info messages) */\n issues: ValidationIssue[];\n}\n\n/**\n * Types of errors that can occur during puzzle import.\n *\n * - `invalid_format`: The file format is not supported or recognized\n * - `parsing_error`: The file format is valid but parsing failed\n * - `unknown`: An unexpected error occurred during import\n */\nexport type ImportErrorType = \"invalid_format\" | \"parsing_error\" | \"unknown\";\n\n/**\n * Custom error class for workshop import failures. Thrown by the `onImport`\n * function when a puzzle cannot be imported.\n *\n * @example\n *\n * ```typescript\n * throw new WorkshopImportError(\n * \"invalid_format\",\n * \"Unsupported file extension: .xyz\",\n * );\n * ```\n */\nexport class WorkshopImportError extends Error {\n constructor(\n /** The category of import error */\n public type: ImportErrorType,\n /** Human-readable error message */\n message: string,\n /** Optional underlying error that caused the import to fail */\n public originalError?: unknown,\n ) {\n super(message);\n this.name = \"WorkshopImportError\";\n }\n}\n\n/**\n * Result of a successful puzzle import operation. Contains the converted puzzle\n * data and optional metadata.\n */\nexport interface ImportResult {\n /**\n * The converted puzzle data in the target format (e.g., XD format for\n * crosswords)\n */\n data: string;\n /** Optional validation warnings about the imported puzzle */\n warnings?: ValidationIssue[];\n /** Optional puzzle title extracted from the import file */\n title?: string;\n /** Optional list of puzzle authors */\n authors?: string[];\n /** Optional list of puzzle editors */\n editors?: string[];\n}\n\n/**\n * Main interface for a Workshop bundle. Workshop bundles are dynamically loaded\n * modules that provide game-specific functionality for puzzle validation and\n * import.\n *\n * @example\n *\n * ```typescript\n * // In your workshop bundle (e.g., games/crossword/src/workshop/index.ts)\n * export const validator = {\n * validate(data: string): ValidationReport {\n * // Custom validation logic\n * return { success: true, issues: [] };\n * },\n * };\n *\n * export const importer = {\n * async onImport(\n * filename: string,\n * contents: string | ArrayBuffer,\n * ): Promise<ImportResult> {\n * // Custom import logic\n * return { data: convertedData };\n * },\n * };\n * ```\n */\nexport interface WorkshopBundle {\n /** Required validator for puzzle data validation */\n validator: {\n /**\n * Validates puzzle data and returns a report of issues.\n *\n * @param data - The raw puzzle data string to validate\n *\n * @returns Validation report with success status and any issues found\n */\n validate(data: string): Promise<ValidationReport> | ValidationReport;\n };\n /** Optional importer for converting external puzzle file formats */\n importer?: {\n /**\n * Imports a puzzle file and converts it to the game's native format. Should\n * throw `WorkshopImportError` for known failure cases.\n *\n * @param filename - Name of the file being imported\n * @param contents - Raw file contents (string for\n * text files, ArrayBuffer for binary)\n *\n * @returns Import result with converted data and optional metadata\n *\n * @throws {WorkshopImportError} For invalid or unsupported files\n */\n onImport(\n filename: string,\n contents: string | ArrayBuffer,\n ): Promise<ImportResult> | ImportResult;\n };\n}\n","import { GameConfig } from \"./puzzmoSDK\";\n\n// Export the auto-generated public SDK types\nexport type * from \"./puzzmoSDK\";\n\n// Export workshop types\nexport * from \"./workshop\";\n\n/**\n * Creates a Puzzmo SDK instance\n *\n * @param config - Configuration options\n *\n * @returns A Puzzmo SDK instance\n */\nexport function createPuzzmoSDK(config: GameConfig) {\n return {\n hello: () => {\n console.log(\"Hello from Puzzmo SDK!\", config);\n },\n };\n}\n\nexport type PuzzmoSDK = ReturnType<typeof createPuzzmoSDK>;\n"],"names":["WorkshopImportError","type","message","originalError","createPuzzmoSDK","config"],"mappings":"wCA2DO,MAAMA,UAA4B,KAAM,CAC7C,YAESC,EAEPC,EAEOC,EACP,CACA,MAAMD,CAAO,EANN,KAAA,KAAAD,EAIA,KAAA,cAAAE,EAGP,KAAK,KAAO,qBACd,CACF,CCxDO,SAASC,EAAgBC,EAAoB,CAClD,MAAO,CACL,MAAO,IAAM,CACX,QAAQ,IAAI,yBAA0BA,CAAM,CAC9C,CAAA,CAEJ"}
package/dist/index.js CHANGED
@@ -1,11 +1,17 @@
1
- function o() {
2
- return "Hello from Puzzmo SDK!";
1
+ class s extends Error {
2
+ constructor(o, t, e) {
3
+ super(t), this.type = o, this.originalError = e, this.name = "WorkshopImportError";
4
+ }
3
5
  }
4
- function r() {
5
- return "0.0.1";
6
+ function l(r) {
7
+ return {
8
+ hello: () => {
9
+ console.log("Hello from Puzzmo SDK!", r);
10
+ }
11
+ };
6
12
  }
7
13
  export {
8
- r as getVersion,
9
- o as helloWorld
14
+ s as WorkshopImportError,
15
+ l as createPuzzmoSDK
10
16
  };
11
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Puzzmo SDK\n * Provides runtime and API access for Puzzmo games\n */\n\n/**\n * Returns a hello world message from the Puzzmo SDK\n * @returns A greeting message\n */\nexport function helloWorld(): string {\n return \"Hello from Puzzmo SDK!\"\n}\n\n/**\n * Returns the SDK version\n * @returns The current SDK version\n */\nexport function getVersion(): string {\n return \"0.0.1\"\n}\n"],"names":["helloWorld","getVersion"],"mappings":"AASO,SAASA,IAAqB;AACnC,SAAO;AACT;AAMO,SAASC,IAAqB;AACnC,SAAO;AACT;"}
1
+ {"version":3,"file":"index.js","sources":["../src/workshop.ts","../src/index.ts"],"sourcesContent":["/**\n * Severity level for validation issues.\n *\n * - `error`: Critical issue that prevents puzzle from being valid\n * - `warning`: Issue that should be addressed but doesn't prevent usage\n * - `info`: Informational message about the puzzle\n */\nexport type ValidationLevel = \"error\" | \"warning\" | \"info\";\n\n/** Represents a single validation issue found during puzzle validation. */\nexport interface ValidationIssue {\n /** Severity level of this validation issue */\n level: ValidationLevel;\n /** Human-readable description of the issue */\n message: string;\n /** Line number in the puzzle data where the issue occurs (1-indexed, optional) */\n line?: number;\n /**\n * Column position in the puzzle data where the issue occurs (1-indexed,\n * optional)\n */\n col?: number;\n /** Length of the problematic text segment for highlighting (optional) */\n length?: number;\n}\n\n/**\n * Complete validation report for a puzzle. Contains the overall validation\n * status and any issues found.\n */\nexport interface ValidationReport {\n /** Whether the puzzle passed validation without errors */\n success: boolean;\n /** Array of validation issues found (errors, warnings, and info messages) */\n issues: ValidationIssue[];\n}\n\n/**\n * Types of errors that can occur during puzzle import.\n *\n * - `invalid_format`: The file format is not supported or recognized\n * - `parsing_error`: The file format is valid but parsing failed\n * - `unknown`: An unexpected error occurred during import\n */\nexport type ImportErrorType = \"invalid_format\" | \"parsing_error\" | \"unknown\";\n\n/**\n * Custom error class for workshop import failures. Thrown by the `onImport`\n * function when a puzzle cannot be imported.\n *\n * @example\n *\n * ```typescript\n * throw new WorkshopImportError(\n * \"invalid_format\",\n * \"Unsupported file extension: .xyz\",\n * );\n * ```\n */\nexport class WorkshopImportError extends Error {\n constructor(\n /** The category of import error */\n public type: ImportErrorType,\n /** Human-readable error message */\n message: string,\n /** Optional underlying error that caused the import to fail */\n public originalError?: unknown,\n ) {\n super(message);\n this.name = \"WorkshopImportError\";\n }\n}\n\n/**\n * Result of a successful puzzle import operation. Contains the converted puzzle\n * data and optional metadata.\n */\nexport interface ImportResult {\n /**\n * The converted puzzle data in the target format (e.g., XD format for\n * crosswords)\n */\n data: string;\n /** Optional validation warnings about the imported puzzle */\n warnings?: ValidationIssue[];\n /** Optional puzzle title extracted from the import file */\n title?: string;\n /** Optional list of puzzle authors */\n authors?: string[];\n /** Optional list of puzzle editors */\n editors?: string[];\n}\n\n/**\n * Main interface for a Workshop bundle. Workshop bundles are dynamically loaded\n * modules that provide game-specific functionality for puzzle validation and\n * import.\n *\n * @example\n *\n * ```typescript\n * // In your workshop bundle (e.g., games/crossword/src/workshop/index.ts)\n * export const validator = {\n * validate(data: string): ValidationReport {\n * // Custom validation logic\n * return { success: true, issues: [] };\n * },\n * };\n *\n * export const importer = {\n * async onImport(\n * filename: string,\n * contents: string | ArrayBuffer,\n * ): Promise<ImportResult> {\n * // Custom import logic\n * return { data: convertedData };\n * },\n * };\n * ```\n */\nexport interface WorkshopBundle {\n /** Required validator for puzzle data validation */\n validator: {\n /**\n * Validates puzzle data and returns a report of issues.\n *\n * @param data - The raw puzzle data string to validate\n *\n * @returns Validation report with success status and any issues found\n */\n validate(data: string): Promise<ValidationReport> | ValidationReport;\n };\n /** Optional importer for converting external puzzle file formats */\n importer?: {\n /**\n * Imports a puzzle file and converts it to the game's native format. Should\n * throw `WorkshopImportError` for known failure cases.\n *\n * @param filename - Name of the file being imported\n * @param contents - Raw file contents (string for\n * text files, ArrayBuffer for binary)\n *\n * @returns Import result with converted data and optional metadata\n *\n * @throws {WorkshopImportError} For invalid or unsupported files\n */\n onImport(\n filename: string,\n contents: string | ArrayBuffer,\n ): Promise<ImportResult> | ImportResult;\n };\n}\n","import { GameConfig } from \"./puzzmoSDK\";\n\n// Export the auto-generated public SDK types\nexport type * from \"./puzzmoSDK\";\n\n// Export workshop types\nexport * from \"./workshop\";\n\n/**\n * Creates a Puzzmo SDK instance\n *\n * @param config - Configuration options\n *\n * @returns A Puzzmo SDK instance\n */\nexport function createPuzzmoSDK(config: GameConfig) {\n return {\n hello: () => {\n console.log(\"Hello from Puzzmo SDK!\", config);\n },\n };\n}\n\nexport type PuzzmoSDK = ReturnType<typeof createPuzzmoSDK>;\n"],"names":["WorkshopImportError","type","message","originalError","createPuzzmoSDK","config"],"mappings":"AA2DO,MAAMA,UAA4B,MAAM;AAAA,EAC7C,YAESC,GAEPC,GAEOC,GACP;AACA,UAAMD,CAAO,GANN,KAAA,OAAAD,GAIA,KAAA,gBAAAE,GAGP,KAAK,OAAO;AAAA,EACd;AACF;ACxDO,SAASC,EAAgBC,GAAoB;AAClD,SAAO;AAAA,IACL,OAAO,MAAM;AACX,cAAQ,IAAI,0BAA0BA,CAAM;AAAA,IAC9C;AAAA,EAAA;AAEJ;"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(e,o){typeof exports=="object"&&typeof module!="undefined"?o(exports):typeof define=="function"&&define.amd?define(["exports"],o):(e=typeof globalThis!="undefined"?globalThis:e||self,o(e.PuzzmoSDK={}))})(this,function(e){"use strict";function o(){return"Hello from Puzzmo SDK!"}function n(){return"0.0.1"}e.getVersion=n,e.helloWorld=o,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
1
+ (function(o,e){typeof exports=="object"&&typeof module!="undefined"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):(o=typeof globalThis!="undefined"?globalThis:o||self,e(o.PuzzmoSDK={}))})(this,(function(o){"use strict";class e extends Error{constructor(n,i,s){super(i),this.type=n,this.originalError=s,this.name="WorkshopImportError"}}function t(r){return{hello:()=>{console.log("Hello from Puzzmo SDK!",r)}}}o.WorkshopImportError=e,o.createPuzzmoSDK=t,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * Puzzmo SDK\n * Provides runtime and API access for Puzzmo games\n */\n\n/**\n * Returns a hello world message from the Puzzmo SDK\n * @returns A greeting message\n */\nexport function helloWorld(): string {\n return \"Hello from Puzzmo SDK!\"\n}\n\n/**\n * Returns the SDK version\n * @returns The current SDK version\n */\nexport function getVersion(): string {\n return \"0.0.1\"\n}\n"],"names":["helloWorld","getVersion"],"mappings":"mPASO,SAASA,GAAqB,CACnC,MAAO,wBACT,CAMO,SAASC,GAAqB,CACnC,MAAO,OACT"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/workshop.ts","../src/index.ts"],"sourcesContent":["/**\n * Severity level for validation issues.\n *\n * - `error`: Critical issue that prevents puzzle from being valid\n * - `warning`: Issue that should be addressed but doesn't prevent usage\n * - `info`: Informational message about the puzzle\n */\nexport type ValidationLevel = \"error\" | \"warning\" | \"info\";\n\n/** Represents a single validation issue found during puzzle validation. */\nexport interface ValidationIssue {\n /** Severity level of this validation issue */\n level: ValidationLevel;\n /** Human-readable description of the issue */\n message: string;\n /** Line number in the puzzle data where the issue occurs (1-indexed, optional) */\n line?: number;\n /**\n * Column position in the puzzle data where the issue occurs (1-indexed,\n * optional)\n */\n col?: number;\n /** Length of the problematic text segment for highlighting (optional) */\n length?: number;\n}\n\n/**\n * Complete validation report for a puzzle. Contains the overall validation\n * status and any issues found.\n */\nexport interface ValidationReport {\n /** Whether the puzzle passed validation without errors */\n success: boolean;\n /** Array of validation issues found (errors, warnings, and info messages) */\n issues: ValidationIssue[];\n}\n\n/**\n * Types of errors that can occur during puzzle import.\n *\n * - `invalid_format`: The file format is not supported or recognized\n * - `parsing_error`: The file format is valid but parsing failed\n * - `unknown`: An unexpected error occurred during import\n */\nexport type ImportErrorType = \"invalid_format\" | \"parsing_error\" | \"unknown\";\n\n/**\n * Custom error class for workshop import failures. Thrown by the `onImport`\n * function when a puzzle cannot be imported.\n *\n * @example\n *\n * ```typescript\n * throw new WorkshopImportError(\n * \"invalid_format\",\n * \"Unsupported file extension: .xyz\",\n * );\n * ```\n */\nexport class WorkshopImportError extends Error {\n constructor(\n /** The category of import error */\n public type: ImportErrorType,\n /** Human-readable error message */\n message: string,\n /** Optional underlying error that caused the import to fail */\n public originalError?: unknown,\n ) {\n super(message);\n this.name = \"WorkshopImportError\";\n }\n}\n\n/**\n * Result of a successful puzzle import operation. Contains the converted puzzle\n * data and optional metadata.\n */\nexport interface ImportResult {\n /**\n * The converted puzzle data in the target format (e.g., XD format for\n * crosswords)\n */\n data: string;\n /** Optional validation warnings about the imported puzzle */\n warnings?: ValidationIssue[];\n /** Optional puzzle title extracted from the import file */\n title?: string;\n /** Optional list of puzzle authors */\n authors?: string[];\n /** Optional list of puzzle editors */\n editors?: string[];\n}\n\n/**\n * Main interface for a Workshop bundle. Workshop bundles are dynamically loaded\n * modules that provide game-specific functionality for puzzle validation and\n * import.\n *\n * @example\n *\n * ```typescript\n * // In your workshop bundle (e.g., games/crossword/src/workshop/index.ts)\n * export const validator = {\n * validate(data: string): ValidationReport {\n * // Custom validation logic\n * return { success: true, issues: [] };\n * },\n * };\n *\n * export const importer = {\n * async onImport(\n * filename: string,\n * contents: string | ArrayBuffer,\n * ): Promise<ImportResult> {\n * // Custom import logic\n * return { data: convertedData };\n * },\n * };\n * ```\n */\nexport interface WorkshopBundle {\n /** Required validator for puzzle data validation */\n validator: {\n /**\n * Validates puzzle data and returns a report of issues.\n *\n * @param data - The raw puzzle data string to validate\n *\n * @returns Validation report with success status and any issues found\n */\n validate(data: string): Promise<ValidationReport> | ValidationReport;\n };\n /** Optional importer for converting external puzzle file formats */\n importer?: {\n /**\n * Imports a puzzle file and converts it to the game's native format. Should\n * throw `WorkshopImportError` for known failure cases.\n *\n * @param filename - Name of the file being imported\n * @param contents - Raw file contents (string for\n * text files, ArrayBuffer for binary)\n *\n * @returns Import result with converted data and optional metadata\n *\n * @throws {WorkshopImportError} For invalid or unsupported files\n */\n onImport(\n filename: string,\n contents: string | ArrayBuffer,\n ): Promise<ImportResult> | ImportResult;\n };\n}\n","import { GameConfig } from \"./puzzmoSDK\";\n\n// Export the auto-generated public SDK types\nexport type * from \"./puzzmoSDK\";\n\n// Export workshop types\nexport * from \"./workshop\";\n\n/**\n * Creates a Puzzmo SDK instance\n *\n * @param config - Configuration options\n *\n * @returns A Puzzmo SDK instance\n */\nexport function createPuzzmoSDK(config: GameConfig) {\n return {\n hello: () => {\n console.log(\"Hello from Puzzmo SDK!\", config);\n },\n };\n}\n\nexport type PuzzmoSDK = ReturnType<typeof createPuzzmoSDK>;\n"],"names":["WorkshopImportError","type","message","originalError","createPuzzmoSDK","config"],"mappings":"oPA2DO,MAAMA,UAA4B,KAAM,CAC7C,YAESC,EAEPC,EAEOC,EACP,CACA,MAAMD,CAAO,EANN,KAAA,KAAAD,EAIA,KAAA,cAAAE,EAGP,KAAK,KAAO,qBACd,CACF,CCxDO,SAASC,EAAgBC,EAAoB,CAClD,MAAO,CACL,MAAO,IAAM,CACX,QAAQ,IAAI,yBAA0BA,CAAM,CAC9C,CAAA,CAEJ"}
@@ -0,0 +1,237 @@
1
+ /** Puzzmo SDK Type Definitions. */
2
+
3
+ /**
4
+ * The API contract between the Puzzmo game runtime, and the game. Contains a
5
+ * space for different objects to handle responsibilities (via the
6
+ * delegates/loaders)
7
+ */
8
+ export type GameConfig = {
9
+ /**
10
+ * An agreement between the game runner, and the games implementation
11
+ * details about the fns in this type any breaking changes to how the run
12
+ * time works will need to be handled by looking at this string version.
13
+ */
14
+ runtimeContract?: "1.0";
15
+ /** The functions for setting up the game state */
16
+ loader: GameDataLoader;
17
+ /**
18
+ * Get updates from the user-oriented changes to the puzzle board: either
19
+ * everything or one when it's useful
20
+ */
21
+ stateSubscriber?: GameStateSubscriber;
22
+ /** Lets the game DI in the color scheme for a game */
23
+ theme: Theme;
24
+ /** Lets a game handle lifecycle events which come from the host downwards */
25
+ setLifecycleSubscriber: (sub: () => GameLifecycleSubscriber) => void;
26
+ };
27
+
28
+ /**
29
+ * The way to think about is is the lifecycle subscriber is that it provides
30
+ * hooks which the game will listen to
31
+ */
32
+ export type GameLifecycleSubscriber = {
33
+ /**
34
+ * When the theme changes in the Puzzmo app, also update the theme in the
35
+ * embed/game.
36
+ */
37
+ updateTheme: (theme: Theme) => void;
38
+ /** App starts the timer when it is ready */
39
+ startGame: () => void;
40
+ };
41
+
42
+ /** A dumb 'json object' settings thing */
43
+ export type GameSettingsUIComponents =
44
+ | {
45
+ id: string;
46
+ type: "title";
47
+ value: string;
48
+ }
49
+ | {
50
+ id: string;
51
+ type: "subtitle";
52
+ value: string;
53
+ }
54
+ | {
55
+ id: string;
56
+ type: "paragraph";
57
+ value: string;
58
+ }
59
+ | {
60
+ id: string;
61
+ type: "text";
62
+ name: string;
63
+ defaultValue: string;
64
+ title: string;
65
+ subtitle?: string | (() => any);
66
+ textarea?: true;
67
+ }
68
+ | {
69
+ id: string;
70
+ type: "number";
71
+ name: string;
72
+ defaultValue: number;
73
+ values: number[];
74
+ title: string;
75
+ subtitle?: string;
76
+ }
77
+ | {
78
+ id: string;
79
+ type: "boolean";
80
+ name: string;
81
+ defaultValue: boolean;
82
+ title: string;
83
+ subtitle?: string;
84
+ }
85
+ | {
86
+ id: string;
87
+ type: "enum";
88
+ name: string;
89
+ defaultValue: string;
90
+ values: string[];
91
+ displays: string[];
92
+ title: string;
93
+ subtitle?: string;
94
+ }
95
+ | {
96
+ id: string;
97
+ type: "setOptions";
98
+ label: string;
99
+ title: string;
100
+ subtitle?: string;
101
+ values: any;
102
+ bgKey: keyof Theme;
103
+ colorKey: keyof Theme;
104
+ }
105
+ | {
106
+ id: string;
107
+ type: "separator";
108
+ key: string;
109
+ }
110
+ | {
111
+ id: string;
112
+ type: "split";
113
+ content: GameSettingsUIComponents[];
114
+ };
115
+
116
+ /**
117
+ * An object which if set will receive internal state updates and callbacks from
118
+ * the inside the game.
119
+ */
120
+ export type GameStateSubscriber = {
121
+ /** The callback when a game is completed */
122
+ gameCompleted: (
123
+ /** The internal state string of the completed game */
124
+ state: string,
125
+ /**
126
+ * The essentials, though metrics* fields are replaced by deeds which can be
127
+ * accessed via `config`
128
+ */
129
+ play: Partial<GamePlay>,
130
+ /** These are legacy options, newer games will send an empty [] */
131
+ pipelineStats: any[],
132
+ // For a small period of time, we sent leaderboards and deeds in this and the next arg positions, so you
133
+ // should take into account that a game may send these from the past
134
+ // Older game builds would not send this object
135
+ config?: AugmentationConfig,
136
+ ) => void;
137
+ /** This function will get called whenever the user's state has changed */
138
+ userInputStringChanged: (state: string, play?: Partial<GamePlay>) => void;
139
+ /** The callback when a game has started booting up */
140
+ gameLaunched?: (state: any, gameRuntimeContractVersion: string) => void;
141
+ /** The callback when game victory animation has finished */
142
+ showGameCompleteScreen: (
143
+ context: MessagesSentFromEmbed["SHOW_GAME_COMPLETE_SCREEN"],
144
+ ) => void;
145
+ };
146
+
147
+ export interface KeyboardConfig {
148
+ /**
149
+ * Whether the keyboard should be shown. Optional legacy property.
150
+ *
151
+ * @deprecated Use the showKeyboard prop on PlayGameKeyboard instead
152
+ */
153
+ show?: boolean;
154
+ /**
155
+ * Custom CSS styles to apply to individual keys, keyed by the character.
156
+ * These styles are merged with the general keyStyles for each key.
157
+ */
158
+ individualKeyStyles?: {
159
+ [key: string]: {
160
+ text: CSSProperties;
161
+ background: CSSProperties;
162
+ };
163
+ };
164
+ /**
165
+ * Custom CSS styles to apply to individual keys. Can be either React
166
+ * CSSProperties or a string-based style object for compatibility with
167
+ * different styling systems.
168
+ */
169
+ keyStyles?:
170
+ | CSSProperties
171
+ | {
172
+ [prop: string]: string;
173
+ };
174
+ /**
175
+ * Custom CSS styles to apply to the entire keyboard container. Uses
176
+ * string-based properties for maximum compatibility.
177
+ */
178
+ kbdStyles?: {
179
+ [prop: string]: string;
180
+ };
181
+ /**
182
+ * Enables drag cursor functionality, allowing users to drag across the
183
+ * keyboard to position a cursor before releasing to select a key. Useful
184
+ * for precise input.
185
+ */
186
+ supportsDragCursor: boolean;
187
+ /**
188
+ * Defines the keyboard layout as rows of characters. Can be either:
189
+ *
190
+ * - A 4-tuple for standard QWERTY-style layouts [row1, row2, row3, row4?]
191
+ * - An array of strings/nulls for custom layouts (null = empty row) Each
192
+ * string represents one row, with each character being one key.
193
+ */
194
+ layout: [string, string, string, string | undefined] | (string | null)[];
195
+ /**
196
+ * Maps character keys to display symbols or special commands. Key =
197
+ * character in layout, Value = what to display/send to game Example: { "≥":
198
+ * ">" } displays ">" but sends "≥" to the game
199
+ */
200
+ symbols: Record<string, string>;
201
+ /**
202
+ * Set of keys that should be visually highlighted (different background
203
+ * color). Commonly used to indicate special keys or current selection
204
+ * state.
205
+ */
206
+ highlight: Set<string>;
207
+ /**
208
+ * Set of keys that should be disabled (non-interactive, grayed out). Used
209
+ * to prevent input of invalid characters in current game state.
210
+ */
211
+ disabled: Set<string>;
212
+ /**
213
+ * Set of keys that should be extra-large (17.85% width vs normal 9.75%).
214
+ * Typically used for important keys like space or enter.
215
+ */
216
+ xl: Set<string>;
217
+ /**
218
+ * Set of keys that should be large (14.7% width vs normal 9.75%). Used for
219
+ * moderately important keys that need more space.
220
+ */
221
+ l: Set<string>;
222
+ /**
223
+ * Controls horizontal alignment of each keyboard row. Array index
224
+ * corresponds to layout row index.
225
+ *
226
+ * - "start" = left-aligned
227
+ * - "center" = center-aligned (default)
228
+ * - "end" = right-aligned
229
+ * - Undefined = use default (center)
230
+ */
231
+ rowPositioning?: ("end" | "start" | "center" | undefined)[];
232
+ /**
233
+ * Set of keys that should grow to fill available horizontal space. Useful
234
+ * for spacebar-like keys that should expand to fill the row.
235
+ */
236
+ flexGrowSymbols?: Set<string>;
237
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Severity level for validation issues.
3
+ *
4
+ * - `error`: Critical issue that prevents puzzle from being valid
5
+ * - `warning`: Issue that should be addressed but doesn't prevent usage
6
+ * - `info`: Informational message about the puzzle
7
+ */
8
+ export type ValidationLevel = "error" | "warning" | "info";
9
+ /** Represents a single validation issue found during puzzle validation. */
10
+ export interface ValidationIssue {
11
+ /** Severity level of this validation issue */
12
+ level: ValidationLevel;
13
+ /** Human-readable description of the issue */
14
+ message: string;
15
+ /** Line number in the puzzle data where the issue occurs (1-indexed, optional) */
16
+ line?: number;
17
+ /**
18
+ * Column position in the puzzle data where the issue occurs (1-indexed,
19
+ * optional)
20
+ */
21
+ col?: number;
22
+ /** Length of the problematic text segment for highlighting (optional) */
23
+ length?: number;
24
+ }
25
+ /**
26
+ * Complete validation report for a puzzle. Contains the overall validation
27
+ * status and any issues found.
28
+ */
29
+ export interface ValidationReport {
30
+ /** Whether the puzzle passed validation without errors */
31
+ success: boolean;
32
+ /** Array of validation issues found (errors, warnings, and info messages) */
33
+ issues: ValidationIssue[];
34
+ }
35
+ /**
36
+ * Types of errors that can occur during puzzle import.
37
+ *
38
+ * - `invalid_format`: The file format is not supported or recognized
39
+ * - `parsing_error`: The file format is valid but parsing failed
40
+ * - `unknown`: An unexpected error occurred during import
41
+ */
42
+ export type ImportErrorType = "invalid_format" | "parsing_error" | "unknown";
43
+ /**
44
+ * Custom error class for workshop import failures. Thrown by the `onImport`
45
+ * function when a puzzle cannot be imported.
46
+ *
47
+ * @example
48
+ *
49
+ * ```typescript
50
+ * throw new WorkshopImportError(
51
+ * "invalid_format",
52
+ * "Unsupported file extension: .xyz",
53
+ * );
54
+ * ```
55
+ */
56
+ export declare class WorkshopImportError extends Error {
57
+ /** The category of import error */
58
+ type: ImportErrorType;
59
+ /** Optional underlying error that caused the import to fail */
60
+ originalError?: unknown | undefined;
61
+ constructor(
62
+ /** The category of import error */
63
+ type: ImportErrorType,
64
+ /** Human-readable error message */
65
+ message: string,
66
+ /** Optional underlying error that caused the import to fail */
67
+ originalError?: unknown | undefined);
68
+ }
69
+ /**
70
+ * Result of a successful puzzle import operation. Contains the converted puzzle
71
+ * data and optional metadata.
72
+ */
73
+ export interface ImportResult {
74
+ /**
75
+ * The converted puzzle data in the target format (e.g., XD format for
76
+ * crosswords)
77
+ */
78
+ data: string;
79
+ /** Optional validation warnings about the imported puzzle */
80
+ warnings?: ValidationIssue[];
81
+ /** Optional puzzle title extracted from the import file */
82
+ title?: string;
83
+ /** Optional list of puzzle authors */
84
+ authors?: string[];
85
+ /** Optional list of puzzle editors */
86
+ editors?: string[];
87
+ }
88
+ /**
89
+ * Main interface for a Workshop bundle. Workshop bundles are dynamically loaded
90
+ * modules that provide game-specific functionality for puzzle validation and
91
+ * import.
92
+ *
93
+ * @example
94
+ *
95
+ * ```typescript
96
+ * // In your workshop bundle (e.g., games/crossword/src/workshop/index.ts)
97
+ * export const validator = {
98
+ * validate(data: string): ValidationReport {
99
+ * // Custom validation logic
100
+ * return { success: true, issues: [] };
101
+ * },
102
+ * };
103
+ *
104
+ * export const importer = {
105
+ * async onImport(
106
+ * filename: string,
107
+ * contents: string | ArrayBuffer,
108
+ * ): Promise<ImportResult> {
109
+ * // Custom import logic
110
+ * return { data: convertedData };
111
+ * },
112
+ * };
113
+ * ```
114
+ */
115
+ export interface WorkshopBundle {
116
+ /** Required validator for puzzle data validation */
117
+ validator: {
118
+ /**
119
+ * Validates puzzle data and returns a report of issues.
120
+ *
121
+ * @param data - The raw puzzle data string to validate
122
+ *
123
+ * @returns Validation report with success status and any issues found
124
+ */
125
+ validate(data: string): Promise<ValidationReport> | ValidationReport;
126
+ };
127
+ /** Optional importer for converting external puzzle file formats */
128
+ importer?: {
129
+ /**
130
+ * Imports a puzzle file and converts it to the game's native format. Should
131
+ * throw `WorkshopImportError` for known failure cases.
132
+ *
133
+ * @param filename - Name of the file being imported
134
+ * @param contents - Raw file contents (string for
135
+ * text files, ArrayBuffer for binary)
136
+ *
137
+ * @returns Import result with converted data and optional metadata
138
+ *
139
+ * @throws {WorkshopImportError} For invalid or unsupported files
140
+ */
141
+ onImport(filename: string, contents: string | ArrayBuffer): Promise<ImportResult> | ImportResult;
142
+ };
143
+ }
144
+ //# sourceMappingURL=workshop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workshop.d.ts","sourceRoot":"","sources":["../src/workshop.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAE3D,2EAA2E;AAC3E,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,KAAK,EAAE,eAAe,CAAC;IACvB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC;IACjB,6EAA6E;IAC7E,MAAM,EAAE,eAAe,EAAE,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,eAAe,GAAG,SAAS,CAAC;AAE7E;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,mCAAmC;IAC5B,IAAI,EAAE,eAAe;IAG5B,+DAA+D;IACxD,aAAa,CAAC,EAAE,OAAO;;IAL9B,mCAAmC;IAC5B,IAAI,EAAE,eAAe;IAC5B,mCAAmC;IACnC,OAAO,EAAE,MAAM;IACf,+DAA+D;IACxD,aAAa,CAAC,EAAE,OAAO,YAAA;CAKjC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;IAC7B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,SAAS,EAAE;QACT;;;;;;WAMG;QACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;KACtE,CAAC;IACF,oEAAoE;IACpE,QAAQ,CAAC,EAAE;QACT;;;;;;;;;;;WAWG;QACH,QAAQ,CACN,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GAAG,WAAW,GAC7B,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;KACzC,CAAC;CACH"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@puzzmo/sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Puzzmo runtime and API access for games",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -17,7 +17,10 @@
17
17
  "dist"
18
18
  ],
19
19
  "scripts": {
20
- "build": "vite build && tsc --project tsconfig.build.json",
20
+ "generate-sdk": "tsx scripts/generateSDK.ts",
21
+ "generate-sdk:watch": "tsx scripts/generateSDK.ts --watch",
22
+ "copy-sdk-types": "cp src/puzzmoSDK.d.ts dist/puzzmoSDK.d.ts",
23
+ "build": "yarn generate-sdk && vite build && tsc --project tsconfig.build.json && yarn copy-sdk-types",
21
24
  "type-check": "tsc --noEmit",
22
25
  "test": "vitest run",
23
26
  "test:watch": "vitest"
@@ -39,6 +42,10 @@
39
42
  "registry": "https://registry.npmjs.org/"
40
43
  },
41
44
  "devDependencies": {
45
+ "@puzzmo-com/shared": "^0.0.13358",
46
+ "prettier": "^3.6.2",
47
+ "prettier-plugin-jsdoc": "^1.5.0",
48
+ "tsx": "catalog:",
42
49
  "typescript": "catalog:",
43
50
  "vite": "catalog:",
44
51
  "vitest": "catalog:"