@puzzmo/sdk 1.0.17 → 1.0.19
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.map +1 -1
- package/dist/vite.d.ts +25 -5
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js +15 -3
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/dist/createSimulator-BwucCTnM.js.map +0 -1
package/dist/types.d.ts
CHANGED
|
@@ -15,8 +15,10 @@ export type Theme = {
|
|
|
15
15
|
keyStrong: string;
|
|
16
16
|
/** A lighter version of the bright pink */
|
|
17
17
|
keyLight: string;
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
18
|
+
/**
|
|
19
|
+
* A variant of the key which is always above a certain level of brightness so that you
|
|
20
|
+
* can show dark text on it for games
|
|
21
|
+
*/
|
|
20
22
|
g_key: string;
|
|
21
23
|
/** A secondary color for the brand, in Puzzmo's case this is the puzzmo yellow */
|
|
22
24
|
subBrand: string;
|
|
@@ -34,7 +36,7 @@ export type Theme = {
|
|
|
34
36
|
alt2: string;
|
|
35
37
|
/** Alt color 3, this one is a cute purple */
|
|
36
38
|
alt3: string;
|
|
37
|
-
/** The foreground body text color
|
|
39
|
+
/** The foreground body text color */
|
|
38
40
|
fg: string;
|
|
39
41
|
/** The red for showing errors */
|
|
40
42
|
error: string;
|
|
@@ -154,7 +156,7 @@ export type BootstrapGameData = {
|
|
|
154
156
|
appRuntimeContract: string;
|
|
155
157
|
};
|
|
156
158
|
export type AppBundle = {
|
|
157
|
-
/** Renders a puzzle and optional state string into an SVG
|
|
159
|
+
/** Renders a puzzle and optional state string into an SVG */
|
|
158
160
|
renderThumbnail(puzzleStr: string, inputStr?: string, config?: ThumbnailConfig): string;
|
|
159
161
|
/** Takes an input string, and backtracks to a version somewhere between 0-1 for its completion */
|
|
160
162
|
interpolateInputString?: (inputStr: string, puzzleStr: string, value: number) => {
|
|
@@ -197,39 +199,39 @@ export type ThumbnailConfig = {
|
|
|
197
199
|
* with letter input. Map those characters to display labels via `symbols`.
|
|
198
200
|
*
|
|
199
201
|
* @example
|
|
200
|
-
*
|
|
202
|
+
* // Simple QWERTY keyboard — a good starting point for word games
|
|
201
203
|
*
|
|
202
|
-
*
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
204
|
+
* const config: KeyboardConfig = {
|
|
205
|
+
* layout: ["qwertyuiop", "asdfghjkl", "↵zxcvbnm⌫", undefined],
|
|
206
|
+
* symbols: { "↵": "Enter", "⌫": "bsp" },
|
|
207
|
+
* highlight: ["↵", "⌫"],
|
|
208
|
+
* disabled: [],
|
|
209
|
+
* xl: [],
|
|
210
|
+
* l: ["↵", "⌫"],
|
|
211
|
+
* supportsDragCursor: false,
|
|
212
|
+
* }
|
|
211
213
|
*
|
|
212
214
|
* @example
|
|
213
|
-
*
|
|
214
|
-
*
|
|
215
|
-
*
|
|
215
|
+
* // Crossword keyboard — complex layout with two panels, direction controls, and drag cursor.
|
|
216
|
+
* // Special characters are used as action key tokens; symbols maps them to display labels.
|
|
217
|
+
* // The "∂" key flips cursor direction; "≤"/"≥" move between cells; "✱" switches panels.
|
|
216
218
|
*
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
223
|
-
*
|
|
224
|
-
*
|
|
225
|
-
*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
*
|
|
231
|
-
*
|
|
232
|
-
*
|
|
219
|
+
* const crosswordConfig: KeyboardConfig = {
|
|
220
|
+
* layout: ["qwertyuiop", "∂asdfghjkl⟳", "≤✱zxcvbnm⌫≥"],
|
|
221
|
+
* symbols: {
|
|
222
|
+
* "∂": "flip-down", // switches cursor direction (emitted as key press "∂")
|
|
223
|
+
* "⟳": "flip-across", // alternate direction flip
|
|
224
|
+
* "≤": "prev", // move cursor to previous cell
|
|
225
|
+
* "≥": "next", // move cursor to next cell
|
|
226
|
+
* "✱": "123", // switch to number/rebus panel
|
|
227
|
+
* "⌫": "bsp", // backspace
|
|
228
|
+
* },
|
|
229
|
+
* highlight: ["∂", "⟳", "≤", "≥", "✱", "⌫"],
|
|
230
|
+
* disabled: [],
|
|
231
|
+
* xl: [],
|
|
232
|
+
* l: [],
|
|
233
|
+
* supportsDragCursor: true, // enables the drag-to-position cursor feature
|
|
234
|
+
* }
|
|
233
235
|
*/
|
|
234
236
|
export type KeyboardConfig = {
|
|
235
237
|
/**
|
|
@@ -240,7 +242,8 @@ export type KeyboardConfig = {
|
|
|
240
242
|
* Accepts either a 4-tuple `[row1, row2, row3, row4 | undefined]` or a plain array of
|
|
241
243
|
* strings/nulls (null renders an empty row).
|
|
242
244
|
*
|
|
243
|
-
* @example
|
|
245
|
+
* @example
|
|
246
|
+
* ;["qwertyuiop", "asdfghjkl", "↵zxcvbnm⌫", undefined]
|
|
244
247
|
*/
|
|
245
248
|
layout: [string, string, string, string | undefined] | (string | null)[];
|
|
246
249
|
/**
|
|
@@ -248,7 +251,8 @@ export type KeyboardConfig = {
|
|
|
248
251
|
* The token character is what the game receives in a `keyboardKeyPress` event;
|
|
249
252
|
* the label is purely visual.
|
|
250
253
|
*
|
|
251
|
-
* @example
|
|
254
|
+
* @example
|
|
255
|
+
* { "⌫": "bsp", "↵": "Enter", "✱": "123" }
|
|
252
256
|
*/
|
|
253
257
|
symbols: Record<string, string>;
|
|
254
258
|
/**
|
|
@@ -256,7 +260,8 @@ export type KeyboardConfig = {
|
|
|
256
260
|
* Typically used for action keys (backspace, enter, direction keys) so they
|
|
257
261
|
* stand out from the letter keys.
|
|
258
262
|
*
|
|
259
|
-
* @example
|
|
263
|
+
* @example
|
|
264
|
+
* ;["↵", "⌫"]
|
|
260
265
|
*/
|
|
261
266
|
highlight: string[];
|
|
262
267
|
/**
|
|
@@ -264,21 +269,24 @@ export type KeyboardConfig = {
|
|
|
264
269
|
* Update this array dynamically to disable letters that are no longer valid
|
|
265
270
|
* for the current game state (e.g. letters already placed in a word game).
|
|
266
271
|
*
|
|
267
|
-
* @example
|
|
272
|
+
* @example
|
|
273
|
+
* ;["q", "z", "x"] // letters unavailable given current board state
|
|
268
274
|
*/
|
|
269
275
|
disabled: string[];
|
|
270
276
|
/**
|
|
271
277
|
* Keys that should render at extra-large width (~17.85% of the keyboard row).
|
|
272
278
|
* Use for high-priority action keys like spacebar or a main confirm key.
|
|
273
279
|
*
|
|
274
|
-
* @example
|
|
280
|
+
* @example
|
|
281
|
+
* ;["␣"]
|
|
275
282
|
*/
|
|
276
283
|
xl: string[];
|
|
277
284
|
/**
|
|
278
285
|
* Keys that should render at large width (~14.7% of the keyboard row).
|
|
279
286
|
* Use for secondary action keys like Enter and Backspace that need more touch area.
|
|
280
287
|
*
|
|
281
|
-
* @example
|
|
288
|
+
* @example
|
|
289
|
+
* ;["↵", "⌫"]
|
|
282
290
|
*/
|
|
283
291
|
l: string[];
|
|
284
292
|
/**
|
|
@@ -294,21 +302,24 @@ export type KeyboardConfig = {
|
|
|
294
302
|
* Controls horizontal alignment for each row. Index matches the `layout` row index.
|
|
295
303
|
* Defaults to `"center"` for any row not listed.
|
|
296
304
|
*
|
|
297
|
-
* @example
|
|
305
|
+
* @example
|
|
306
|
+
* ;["center", "center", "end", "center"]
|
|
298
307
|
*/
|
|
299
308
|
rowPositioning?: ("end" | "start" | "center" | undefined)[];
|
|
300
309
|
/**
|
|
301
310
|
* Keys that expand to fill remaining horizontal space in their row (flex-grow).
|
|
302
311
|
* Useful for a spacebar key that should stretch across the bottom row.
|
|
303
312
|
*
|
|
304
|
-
* @example
|
|
313
|
+
* @example
|
|
314
|
+
* ;["␣"]
|
|
305
315
|
*/
|
|
306
316
|
flexGrowSymbols?: string[];
|
|
307
317
|
/**
|
|
308
318
|
* CSS properties applied to every key face. Use for font overrides or color tweaks
|
|
309
319
|
* that apply uniformly across the keyboard.
|
|
310
320
|
*
|
|
311
|
-
* @example
|
|
321
|
+
* @example
|
|
322
|
+
* { textTransform: "lowercase", color: "#888" }
|
|
312
323
|
*/
|
|
313
324
|
keyStyles?: Record<string, string>;
|
|
314
325
|
/**
|
|
@@ -370,7 +381,10 @@ export type MessagesSentFromEmbed = {
|
|
|
370
381
|
* Sent automatically by the SDK every 10 seconds.
|
|
371
382
|
*/
|
|
372
383
|
TIMER_SYNC: number;
|
|
373
|
-
/**
|
|
384
|
+
/**
|
|
385
|
+
* Show or update the on-screen keyboard. Pass the full config each time — the host replaces its entire state. To hide, call
|
|
386
|
+
* `sdk.keyboard.hide()`.
|
|
387
|
+
*/
|
|
374
388
|
KEYBOARD_UPDATE_CONFIG: KeyboardConfig;
|
|
375
389
|
/** Notify the host that a named checkpoint was reached (e.g. completing a sub-puzzle or bonus round). */
|
|
376
390
|
HIT_CHECKPOINT: {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,MAAM,KAAK,GAAG;IAClB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,iCAAiC;IACjC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAA;IACtB,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAA;IACb,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB,2CAA2C;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/vite.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.cjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from \"vite\"\nimport { build } from \"vite\"\nimport path from \"path\"\nimport fs from \"fs\"\n\nexport type PuzzmoSimulatorPluginOptions = {\n /** Whether to auto-start the game after READY (default: true) */\n autoStart?: boolean\n /** Initial collapsed state (default: true) */\n collapsed?: boolean\n /** Glob pattern for fixture files, passed to import.meta.glob which is relative to the closest puzzmo.json. Defaults to \"/fixtures/puzzles/**\\/*.json\". Pass false to disable. */\n fixturesGlob?: string | false\n}\n\nconst simulatorURL = \"/@puzzmo-simulator-init.js\"\nconst virtualID = \"virtual:puzzmo-simulator\"\n\nexport type GameInfo = {\n /** Directory containing the puzzmo.json */\n dir: string\n slug: string\n displayName: string\n /** Vite-root-relative path to app bundle entry, if it exists */\n appBundlePath: string | null\n}\n\n/** Discover all games from puzzmo.json files under a root directory. */\nexport function discoverGames(viteRoot: string): Map<string, GameInfo> {\n const games = new Map<string, GameInfo>()\n const candidates = findPuzzmoJsonDirs(viteRoot, 3)\n if (fs.existsSync(path.join(viteRoot, \"puzzmo.json\"))) {\n candidates.unshift(viteRoot)\n }\n for (const dir of candidates) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(dir, \"puzzmo.json\"), \"utf-8\"))\n if (!data?.game?.slug) continue\n const bundleEntry = path.join(dir, \"src\", \"appBundle.js\")\n let appBundle: string | null = null\n if (fs.existsSync(bundleEntry)) {\n const relative = path.relative(viteRoot, bundleEntry)\n appBundle = \"/\" + relative.split(path.sep).join(\"/\")\n }\n games.set(data.game.slug, { dir, slug: data.game.slug, displayName: data.game.displayName, appBundlePath: appBundle })\n } catch {\n // skip invalid files\n }\n }\n return games\n}\n\n/** Resolve which game a request belongs to using the referer URL */\nexport function resolveGameFromReferer(referer: string | undefined, games: Map<string, GameInfo>, viteRoot: string): GameInfo | undefined {\n if (referer) {\n try {\n const refPath = new URL(referer).pathname\n for (const g of games.values()) {\n const relDir = \"/\" + path.relative(viteRoot, g.dir).split(path.sep).join(\"/\")\n if (refPath.startsWith(relDir + \"/\") || refPath === relDir) return g\n }\n } catch {\n // ignore malformed referer\n }\n }\n if (games.size === 1) return games.values().next().value\n return undefined\n}\n\n/** Generate the virtual module code for the simulator. */\nexport function generateSimulatorCode(options: PuzzmoSimulatorPluginOptions, game: GameInfo | undefined): string {\n const { fixturesGlob: fixturesOpt, ...config } = options\n const fixturesGlob = fixturesOpt === false ? null : (fixturesOpt ?? \"/fixtures/puzzles/**/*.json\")\n\n const lines = [`import { createSimulator } from \"@puzzmo/sdk/simulator\"`]\n\n if (fixturesGlob) {\n lines.push(`const fixtures = import.meta.glob(${JSON.stringify(fixturesGlob)}, { eager: true })`)\n }\n\n if (game?.appBundlePath) {\n lines.push(`import(${JSON.stringify(game.appBundlePath)}).then(m => {`)\n lines.push(` if (m.renderThumbnail) globalThis.renderThumbnail = m.renderThumbnail`)\n lines.push(`}).catch(() => {})`)\n }\n\n const simConfig = { ...config, ...(game?.slug ? { slug: game.slug } : {}) }\n const configEntries = Object.entries(simConfig).filter(([, v]) => v !== undefined)\n const configParts = configEntries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)\n if (fixturesGlob) configParts.push(\"fixtures\")\n\n lines.push(`createSimulator({ ${configParts.join(\", \")} })`)\n\n return lines.join(\"\\n\")\n}\n\n/** Vite plugin that injects the Puzzmo simulator in dev mode and handles OAuth callbacks. */\nexport function puzzmoSimulator(options: PuzzmoSimulatorPluginOptions = {}): Plugin {\n let games = new Map<string, GameInfo>()\n let viteRoot: string\n\n return {\n name: \"puzzmo-simulator\",\n apply: \"serve\",\n\n configResolved(config: ResolvedConfig) {\n viteRoot = config.root\n games = discoverGames(viteRoot)\n\n if (games.size === 0) {\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m\\x1b[2m no puzzmo.json files found\\x1b[22m`)\n } else {\n const names = [...games.values()].map((g) => `\\x1b[36m${g.slug}\\x1b[39m`)\n const label = games.size === 1 ? \"game\" : \"games\"\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m found ${games.size} ${label}: ${names.join(\"\\x1b[2m, \\x1b[22m\")}`)\n }\n },\n\n resolveId(id) {\n if (id === virtualID || id.startsWith(virtualID + \"?\")) return \"\\0\" + id\n },\n\n load(id) {\n if (!id.startsWith(\"\\0\" + virtualID)) return\n const params = new URLSearchParams(id.split(\"?\")[1] || \"\")\n const gameSlug = params.get(\"game\")\n const game = gameSlug ? games.get(gameSlug) : games.size === 1 ? games.values().next().value : undefined\n return generateSimulatorCode(options, game)\n },\n\n configureServer(server) {\n server.middlewares.use(\"/oauth/callback\", (_req, res) => {\n res.setHeader(\"Content-Type\", \"text/html\")\n res.end(`<!DOCTYPE html>\n<html><head><title>Puzzmo OAuth</title></head>\n<body><script>\nvar params = new URLSearchParams(window.location.search);\nvar returnUrl = sessionStorage.getItem(\"oauth_return_url\") || \"/\";\nvar url = new URL(returnUrl);\nparams.forEach(function(v, k) { url.searchParams.set(k, v); });\nwindow.location.href = url.toString();\n</script></body></html>`)\n })\n\n // Serve the simulator init module, resolving the game from the referer\n server.middlewares.use(async (req, res, next) => {\n if (req.url?.split(\"?\")[0] !== simulatorURL) return next()\n\n const game = resolveGameFromReferer(req.headers.referer, games, viteRoot)\n const moduleID = virtualID + (game ? `?game=${game.slug}` : \"\")\n const result = await server.transformRequest(moduleID)\n if (!result) return next()\n res.setHeader(\"Content-Type\", \"application/javascript\")\n res.end(result.code)\n })\n },\n\n transformIndexHtml() {\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\", src: simulatorURL },\n injectTo: \"head\",\n },\n ]\n },\n }\n}\n\ntype BundlePluginOptions = {\n /** Entry file for the bundle */\n entry: string\n /** Output file name */\n outputFile: string\n}\n\nfunction createBundlePlugin(pluginName: string, defaults: BundlePluginOptions) {\n return (options: Partial<BundlePluginOptions> = {}): Plugin => {\n const { entry, outputFile } = { ...defaults, ...options }\n return {\n name: pluginName,\n apply: \"build\",\n async closeBundle() {\n try {\n await build({\n configFile: false,\n logLevel: \"warn\",\n build: {\n lib: {\n entry: path.isAbsolute(entry) ? entry : path.resolve(process.cwd(), entry),\n formats: [\"es\"],\n fileName: () => outputFile,\n },\n outDir: \"dist\",\n emptyOutDir: false,\n },\n })\n } catch (error) {\n console.error(`[${pluginName}] build failed:`, error)\n throw error\n }\n },\n }\n }\n}\n\nexport type AppBundlePluginOptions = Partial<BundlePluginOptions>\n\n/**\n * Vite plugin that produces dist/app-bundle.js after the main build for app-level integrations.\n *\n * The bundle exports `renderThumbnail(puzzleStr, inputStr?, config?)` — a pure\n * SVG-string renderer used by the Puzzmo platform for puzzle previews.\n */\nexport const appBundlePlugin = createBundlePlugin(\"app-bundle\", { entry: \"src/appBundle.js\", outputFile: \"app-bundle.js\" })\n\nexport type EditorBundlePluginOptions = Partial<BundlePluginOptions>\n\n/** Vite plugin that produces dist/editor-bundle.js after the main build for editor-level integrations. */\nexport const editorBundlePlugin = createBundlePlugin(\"editor-bundle\", { entry: \"src/editorBundle.js\", outputFile: \"editor-bundle.js\" })\n\n/** Recursively find directories containing puzzmo.json, up to `maxDepth` levels deep. */\nexport const findPuzzmoJsonDirs = (root: string, maxDepth: number, depth = 0): string[] => {\n if (depth >= maxDepth) return []\n const results: string[] = []\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(root, { withFileTypes: true })\n } catch {\n return results\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue\n const dir = path.join(root, entry.name)\n if (fs.existsSync(path.join(dir, \"puzzmo.json\"))) {\n results.push(dir)\n }\n results.push(...findPuzzmoJsonDirs(dir, maxDepth, depth + 1))\n }\n return results\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite.cjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from \"vite\"\nimport { build } from \"vite\"\nimport path from \"path\"\nimport fs from \"fs\"\n\nexport type PuzzmoSimulatorPluginOptions = {\n /** Whether to auto-start the game after READY (default: true) */\n autoStart?: boolean\n /** Initial collapsed state (default: true) */\n collapsed?: boolean\n /**\n * Glob pattern for fixture files, passed to import.meta.glob which is relative to the closest puzzmo.json. Defaults to\n * `\"/fixtures/puzzles/**\\/*.json\"`. Pass false to disable.\n */\n fixturesGlob?: string | false\n}\n\nconst simulatorURL = \"/@puzzmo-simulator-init.js\"\nconst virtualID = \"virtual:puzzmo-simulator\"\n\n/** @internal */\nexport type GameInfo = {\n /** Directory containing the puzzmo.json */\n dir: string\n slug: string\n displayName: string\n /** Vite-root-relative path to app bundle entry, if it exists */\n appBundlePath: string | null\n}\n\n/**\n * Discover all games from puzzmo.json files under a root directory.\n *\n * @internal\n */\nexport function discoverGames(viteRoot: string): Map<string, GameInfo> {\n const games = new Map<string, GameInfo>()\n const candidates = findPuzzmoJsonDirs(viteRoot, 3)\n if (fs.existsSync(path.join(viteRoot, \"puzzmo.json\"))) {\n candidates.unshift(viteRoot)\n }\n for (const dir of candidates) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(dir, \"puzzmo.json\"), \"utf-8\"))\n if (!data?.game?.slug) continue\n const bundleEntry = path.join(dir, \"src\", \"appBundle.js\")\n let appBundle: string | null = null\n if (fs.existsSync(bundleEntry)) {\n const relative = path.relative(viteRoot, bundleEntry)\n appBundle = \"/\" + relative.split(path.sep).join(\"/\")\n }\n games.set(data.game.slug, { dir, slug: data.game.slug, displayName: data.game.displayName, appBundlePath: appBundle })\n } catch {\n // skip invalid files\n }\n }\n return games\n}\n\n/**\n * Resolve which game a request belongs to using the referer URL.\n *\n * @internal\n */\nexport function resolveGameFromReferer(referer: string | undefined, games: Map<string, GameInfo>, viteRoot: string): GameInfo | undefined {\n if (referer) {\n try {\n const refPath = new URL(referer).pathname\n for (const g of games.values()) {\n const relDir = \"/\" + path.relative(viteRoot, g.dir).split(path.sep).join(\"/\")\n if (refPath.startsWith(relDir + \"/\") || refPath === relDir) return g\n }\n } catch {\n // ignore malformed referer\n }\n }\n if (games.size === 1) return games.values().next().value\n return undefined\n}\n\n/**\n * Generate the virtual module code for the simulator.\n *\n * @internal\n */\nexport function generateSimulatorCode(options: PuzzmoSimulatorPluginOptions, game: GameInfo | undefined): string {\n const { fixturesGlob: fixturesOpt, ...config } = options\n const fixturesGlob = fixturesOpt === false ? null : (fixturesOpt ?? \"/fixtures/puzzles/**/*.json\")\n\n const lines = [`import { createSimulator } from \"@puzzmo/sdk/simulator\"`]\n\n if (fixturesGlob) {\n lines.push(`const fixtures = import.meta.glob(${JSON.stringify(fixturesGlob)}, { eager: true })`)\n }\n\n if (game?.appBundlePath) {\n lines.push(`import(${JSON.stringify(game.appBundlePath)}).then(m => {`)\n lines.push(` if (m.renderThumbnail) globalThis.renderThumbnail = m.renderThumbnail`)\n lines.push(`}).catch(() => {})`)\n }\n\n const simConfig = { ...config, ...(game?.slug ? { slug: game.slug } : {}) }\n const configEntries = Object.entries(simConfig).filter(([, v]) => v !== undefined)\n const configParts = configEntries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)\n if (fixturesGlob) configParts.push(\"fixtures\")\n\n lines.push(`createSimulator({ ${configParts.join(\", \")} })`)\n\n return lines.join(\"\\n\")\n}\n\n/** Vite plugin that injects the Puzzmo simulator in dev mode and handles OAuth callbacks. */\nexport function puzzmoSimulator(options: PuzzmoSimulatorPluginOptions = {}): Plugin {\n let games = new Map<string, GameInfo>()\n let viteRoot: string\n\n return {\n name: \"puzzmo-simulator\",\n apply: \"serve\",\n\n configResolved(config: ResolvedConfig) {\n viteRoot = config.root\n games = discoverGames(viteRoot)\n\n if (games.size === 0) {\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m\\x1b[2m no puzzmo.json files found\\x1b[22m`)\n } else {\n const names = [...games.values()].map((g) => `\\x1b[36m${g.slug}\\x1b[39m`)\n const label = games.size === 1 ? \"game\" : \"games\"\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m found ${games.size} ${label}: ${names.join(\"\\x1b[2m, \\x1b[22m\")}`)\n }\n },\n\n resolveId(id) {\n if (id === virtualID || id.startsWith(virtualID + \"?\")) return \"\\0\" + id\n },\n\n load(id) {\n if (!id.startsWith(\"\\0\" + virtualID)) return\n const params = new URLSearchParams(id.split(\"?\")[1] || \"\")\n const gameSlug = params.get(\"game\")\n const game = gameSlug ? games.get(gameSlug) : games.size === 1 ? games.values().next().value : undefined\n return generateSimulatorCode(options, game)\n },\n\n configureServer(server) {\n server.middlewares.use(\"/oauth/callback\", (_req, res) => {\n res.setHeader(\"Content-Type\", \"text/html\")\n res.end(`<!DOCTYPE html>\n<html><head><title>Puzzmo OAuth</title></head>\n<body><script>\nvar params = new URLSearchParams(window.location.search);\nvar returnUrl = sessionStorage.getItem(\"oauth_return_url\") || \"/\";\nvar url = new URL(returnUrl);\nparams.forEach(function(v, k) { url.searchParams.set(k, v); });\nwindow.location.href = url.toString();\n</script></body></html>`)\n })\n\n // Serve the simulator init module, resolving the game from the referer\n server.middlewares.use(async (req, res, next) => {\n if (req.url?.split(\"?\")[0] !== simulatorURL) return next()\n\n const game = resolveGameFromReferer(req.headers.referer, games, viteRoot)\n const moduleID = virtualID + (game ? `?game=${game.slug}` : \"\")\n const result = await server.transformRequest(moduleID)\n if (!result) return next()\n res.setHeader(\"Content-Type\", \"application/javascript\")\n res.end(result.code)\n })\n },\n\n transformIndexHtml() {\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\", src: simulatorURL },\n injectTo: \"head\",\n },\n ]\n },\n }\n}\n\ntype BundlePluginOptions = {\n /** Entry file for the bundle */\n entry: string\n /** Output file name */\n outputFile: string\n}\n\nfunction createBundlePlugin(pluginName: string, defaults: BundlePluginOptions) {\n return (options: Partial<BundlePluginOptions> = {}): Plugin => {\n const { entry, outputFile } = { ...defaults, ...options }\n return {\n name: pluginName,\n apply: \"build\",\n async closeBundle() {\n try {\n await build({\n configFile: false,\n logLevel: \"warn\",\n build: {\n lib: {\n entry: path.isAbsolute(entry) ? entry : path.resolve(process.cwd(), entry),\n formats: [\"es\"],\n fileName: () => outputFile,\n },\n outDir: \"dist\",\n emptyOutDir: false,\n },\n })\n } catch (error) {\n console.error(`[${pluginName}] build failed:`, error)\n throw error\n }\n },\n }\n }\n}\n\nexport type AppBundlePluginOptions = Partial<BundlePluginOptions>\n\n/**\n * Vite plugin that produces dist/app-bundle.js after the main build for app-level integrations.\n *\n * The bundle exports `renderThumbnail(puzzleStr, inputStr?, config?)` — a pure\n * SVG-string renderer used by the Puzzmo platform for puzzle previews.\n */\nexport const appBundlePlugin = createBundlePlugin(\"app-bundle\", { entry: \"src/appBundle.js\", outputFile: \"app-bundle.js\" })\n\nexport type EditorBundlePluginOptions = Partial<BundlePluginOptions>\n\n/** Vite plugin that produces dist/editor-bundle.js after the main build for editor-level integrations. */\nexport const editorBundlePlugin = createBundlePlugin(\"editor-bundle\", { entry: \"src/editorBundle.js\", outputFile: \"editor-bundle.js\" })\n\n/**\n * Recursively find directories containing puzzmo.json, up to `maxDepth` levels deep.\n *\n * @internal\n */\nexport const findPuzzmoJsonDirs = (root: string, maxDepth: number, depth = 0): string[] => {\n if (depth >= maxDepth) return []\n const results: string[] = []\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(root, { withFileTypes: true })\n } catch {\n return results\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue\n const dir = path.join(root, entry.name)\n if (fs.existsSync(path.join(dir, \"puzzmo.json\"))) {\n results.push(dir)\n }\n results.push(...findPuzzmoJsonDirs(dir, maxDepth, depth + 1))\n }\n return results\n}\n"],"mappings":"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"}
|
package/dist/vite.d.ts
CHANGED
|
@@ -4,9 +4,13 @@ export type PuzzmoSimulatorPluginOptions = {
|
|
|
4
4
|
autoStart?: boolean;
|
|
5
5
|
/** Initial collapsed state (default: true) */
|
|
6
6
|
collapsed?: boolean;
|
|
7
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Glob pattern for fixture files, passed to import.meta.glob which is relative to the closest puzzmo.json. Defaults to
|
|
9
|
+
* `"/fixtures/puzzles/**\/*.json"`. Pass false to disable.
|
|
10
|
+
*/
|
|
8
11
|
fixturesGlob?: string | false;
|
|
9
12
|
};
|
|
13
|
+
/** @internal */
|
|
10
14
|
export type GameInfo = {
|
|
11
15
|
/** Directory containing the puzzmo.json */
|
|
12
16
|
dir: string;
|
|
@@ -15,11 +19,23 @@ export type GameInfo = {
|
|
|
15
19
|
/** Vite-root-relative path to app bundle entry, if it exists */
|
|
16
20
|
appBundlePath: string | null;
|
|
17
21
|
};
|
|
18
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Discover all games from puzzmo.json files under a root directory.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
19
27
|
export declare function discoverGames(viteRoot: string): Map<string, GameInfo>;
|
|
20
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Resolve which game a request belongs to using the referer URL.
|
|
30
|
+
*
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
21
33
|
export declare function resolveGameFromReferer(referer: string | undefined, games: Map<string, GameInfo>, viteRoot: string): GameInfo | undefined;
|
|
22
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Generate the virtual module code for the simulator.
|
|
36
|
+
*
|
|
37
|
+
* @internal
|
|
38
|
+
*/
|
|
23
39
|
export declare function generateSimulatorCode(options: PuzzmoSimulatorPluginOptions, game: GameInfo | undefined): string;
|
|
24
40
|
/** Vite plugin that injects the Puzzmo simulator in dev mode and handles OAuth callbacks. */
|
|
25
41
|
export declare function puzzmoSimulator(options?: PuzzmoSimulatorPluginOptions): Plugin;
|
|
@@ -40,7 +56,11 @@ export declare const appBundlePlugin: (options?: Partial<BundlePluginOptions>) =
|
|
|
40
56
|
export type EditorBundlePluginOptions = Partial<BundlePluginOptions>;
|
|
41
57
|
/** Vite plugin that produces dist/editor-bundle.js after the main build for editor-level integrations. */
|
|
42
58
|
export declare const editorBundlePlugin: (options?: Partial<BundlePluginOptions>) => Plugin<any>;
|
|
43
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Recursively find directories containing puzzmo.json, up to `maxDepth` levels deep.
|
|
61
|
+
*
|
|
62
|
+
* @internal
|
|
63
|
+
*/
|
|
44
64
|
export declare const findPuzzmoJsonDirs: (root: string, maxDepth: number, depth?: number) => string[];
|
|
45
65
|
export {};
|
|
46
66
|
//# sourceMappingURL=vite.d.ts.map
|
package/dist/vite.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAA;AAKlD,MAAM,MAAM,4BAA4B,GAAG;IACzC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB
|
|
1
|
+
{"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAkB,MAAM,MAAM,CAAA;AAKlD,MAAM,MAAM,4BAA4B,GAAG;IACzC,iEAAiE;IACjE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CAC9B,CAAA;AAKD,gBAAgB;AAChB,MAAM,MAAM,QAAQ,GAAG;IACrB,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;CAC7B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAsBrE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAcxI;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,EAAE,IAAI,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAwB/G;AAED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,OAAO,GAAE,4BAAiC,GAAG,MAAM,CAsElF;AAED,KAAK,mBAAmB,GAAG;IACzB,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAgCD,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAEjE;;;;;GAKG;AACH,eAAO,MAAM,eAAe,yDAA+F,CAAA;AAE3H,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAEpE,0GAA0G;AAC1G,eAAO,MAAM,kBAAkB,yDAAwG,CAAA;AAEvI;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8DAkB9B,CAAA"}
|
package/dist/vite.js
CHANGED
|
@@ -22,7 +22,11 @@ function o(e, t) {
|
|
|
22
22
|
return i;
|
|
23
23
|
}
|
|
24
24
|
var s = ["fixturesGlob"], c = "/@puzzmo-simulator-init.js", l = "virtual:puzzmo-simulator";
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* Discover all games from puzzmo.json files under a root directory.
|
|
27
|
+
*
|
|
28
|
+
* @internal
|
|
29
|
+
*/
|
|
26
30
|
function u(e) {
|
|
27
31
|
let t = /* @__PURE__ */ new Map(), n = _(e, 3);
|
|
28
32
|
i.existsSync(r.join(e, "puzzmo.json")) && n.unshift(e);
|
|
@@ -40,7 +44,11 @@ function u(e) {
|
|
|
40
44
|
} catch (e) {}
|
|
41
45
|
return t;
|
|
42
46
|
}
|
|
43
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* Resolve which game a request belongs to using the referer URL.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
44
52
|
function d(e, t, n) {
|
|
45
53
|
if (e) try {
|
|
46
54
|
let i = new URL(e).pathname;
|
|
@@ -51,7 +59,11 @@ function d(e, t, n) {
|
|
|
51
59
|
} catch (e) {}
|
|
52
60
|
if (t.size === 1) return t.values().next().value;
|
|
53
61
|
}
|
|
54
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Generate the virtual module code for the simulator.
|
|
64
|
+
*
|
|
65
|
+
* @internal
|
|
66
|
+
*/
|
|
55
67
|
function f(e, n) {
|
|
56
68
|
let { fixturesGlob: r } = e, i = o(e, s), a = r === !1 ? null : r == null ? "/fixtures/puzzles/**/*.json" : r, c = ["import { createSimulator } from \"@puzzmo/sdk/simulator\""];
|
|
57
69
|
a && c.push(`const fixtures = import.meta.glob(${JSON.stringify(a)}, { eager: true })`), n != null && n.appBundlePath && (c.push(`import(${JSON.stringify(n.appBundlePath)}).then(m => {`), c.push(" if (m.renderThumbnail) globalThis.renderThumbnail = m.renderThumbnail"), c.push("}).catch(() => {})"));
|
package/dist/vite.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.js","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from \"vite\"\nimport { build } from \"vite\"\nimport path from \"path\"\nimport fs from \"fs\"\n\nexport type PuzzmoSimulatorPluginOptions = {\n /** Whether to auto-start the game after READY (default: true) */\n autoStart?: boolean\n /** Initial collapsed state (default: true) */\n collapsed?: boolean\n /** Glob pattern for fixture files, passed to import.meta.glob which is relative to the closest puzzmo.json. Defaults to \"/fixtures/puzzles/**\\/*.json\". Pass false to disable. */\n fixturesGlob?: string | false\n}\n\nconst simulatorURL = \"/@puzzmo-simulator-init.js\"\nconst virtualID = \"virtual:puzzmo-simulator\"\n\nexport type GameInfo = {\n /** Directory containing the puzzmo.json */\n dir: string\n slug: string\n displayName: string\n /** Vite-root-relative path to app bundle entry, if it exists */\n appBundlePath: string | null\n}\n\n/** Discover all games from puzzmo.json files under a root directory. */\nexport function discoverGames(viteRoot: string): Map<string, GameInfo> {\n const games = new Map<string, GameInfo>()\n const candidates = findPuzzmoJsonDirs(viteRoot, 3)\n if (fs.existsSync(path.join(viteRoot, \"puzzmo.json\"))) {\n candidates.unshift(viteRoot)\n }\n for (const dir of candidates) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(dir, \"puzzmo.json\"), \"utf-8\"))\n if (!data?.game?.slug) continue\n const bundleEntry = path.join(dir, \"src\", \"appBundle.js\")\n let appBundle: string | null = null\n if (fs.existsSync(bundleEntry)) {\n const relative = path.relative(viteRoot, bundleEntry)\n appBundle = \"/\" + relative.split(path.sep).join(\"/\")\n }\n games.set(data.game.slug, { dir, slug: data.game.slug, displayName: data.game.displayName, appBundlePath: appBundle })\n } catch {\n // skip invalid files\n }\n }\n return games\n}\n\n/** Resolve which game a request belongs to using the referer URL */\nexport function resolveGameFromReferer(referer: string | undefined, games: Map<string, GameInfo>, viteRoot: string): GameInfo | undefined {\n if (referer) {\n try {\n const refPath = new URL(referer).pathname\n for (const g of games.values()) {\n const relDir = \"/\" + path.relative(viteRoot, g.dir).split(path.sep).join(\"/\")\n if (refPath.startsWith(relDir + \"/\") || refPath === relDir) return g\n }\n } catch {\n // ignore malformed referer\n }\n }\n if (games.size === 1) return games.values().next().value\n return undefined\n}\n\n/** Generate the virtual module code for the simulator. */\nexport function generateSimulatorCode(options: PuzzmoSimulatorPluginOptions, game: GameInfo | undefined): string {\n const { fixturesGlob: fixturesOpt, ...config } = options\n const fixturesGlob = fixturesOpt === false ? null : (fixturesOpt ?? \"/fixtures/puzzles/**/*.json\")\n\n const lines = [`import { createSimulator } from \"@puzzmo/sdk/simulator\"`]\n\n if (fixturesGlob) {\n lines.push(`const fixtures = import.meta.glob(${JSON.stringify(fixturesGlob)}, { eager: true })`)\n }\n\n if (game?.appBundlePath) {\n lines.push(`import(${JSON.stringify(game.appBundlePath)}).then(m => {`)\n lines.push(` if (m.renderThumbnail) globalThis.renderThumbnail = m.renderThumbnail`)\n lines.push(`}).catch(() => {})`)\n }\n\n const simConfig = { ...config, ...(game?.slug ? { slug: game.slug } : {}) }\n const configEntries = Object.entries(simConfig).filter(([, v]) => v !== undefined)\n const configParts = configEntries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)\n if (fixturesGlob) configParts.push(\"fixtures\")\n\n lines.push(`createSimulator({ ${configParts.join(\", \")} })`)\n\n return lines.join(\"\\n\")\n}\n\n/** Vite plugin that injects the Puzzmo simulator in dev mode and handles OAuth callbacks. */\nexport function puzzmoSimulator(options: PuzzmoSimulatorPluginOptions = {}): Plugin {\n let games = new Map<string, GameInfo>()\n let viteRoot: string\n\n return {\n name: \"puzzmo-simulator\",\n apply: \"serve\",\n\n configResolved(config: ResolvedConfig) {\n viteRoot = config.root\n games = discoverGames(viteRoot)\n\n if (games.size === 0) {\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m\\x1b[2m no puzzmo.json files found\\x1b[22m`)\n } else {\n const names = [...games.values()].map((g) => `\\x1b[36m${g.slug}\\x1b[39m`)\n const label = games.size === 1 ? \"game\" : \"games\"\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m found ${games.size} ${label}: ${names.join(\"\\x1b[2m, \\x1b[22m\")}`)\n }\n },\n\n resolveId(id) {\n if (id === virtualID || id.startsWith(virtualID + \"?\")) return \"\\0\" + id\n },\n\n load(id) {\n if (!id.startsWith(\"\\0\" + virtualID)) return\n const params = new URLSearchParams(id.split(\"?\")[1] || \"\")\n const gameSlug = params.get(\"game\")\n const game = gameSlug ? games.get(gameSlug) : games.size === 1 ? games.values().next().value : undefined\n return generateSimulatorCode(options, game)\n },\n\n configureServer(server) {\n server.middlewares.use(\"/oauth/callback\", (_req, res) => {\n res.setHeader(\"Content-Type\", \"text/html\")\n res.end(`<!DOCTYPE html>\n<html><head><title>Puzzmo OAuth</title></head>\n<body><script>\nvar params = new URLSearchParams(window.location.search);\nvar returnUrl = sessionStorage.getItem(\"oauth_return_url\") || \"/\";\nvar url = new URL(returnUrl);\nparams.forEach(function(v, k) { url.searchParams.set(k, v); });\nwindow.location.href = url.toString();\n</script></body></html>`)\n })\n\n // Serve the simulator init module, resolving the game from the referer\n server.middlewares.use(async (req, res, next) => {\n if (req.url?.split(\"?\")[0] !== simulatorURL) return next()\n\n const game = resolveGameFromReferer(req.headers.referer, games, viteRoot)\n const moduleID = virtualID + (game ? `?game=${game.slug}` : \"\")\n const result = await server.transformRequest(moduleID)\n if (!result) return next()\n res.setHeader(\"Content-Type\", \"application/javascript\")\n res.end(result.code)\n })\n },\n\n transformIndexHtml() {\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\", src: simulatorURL },\n injectTo: \"head\",\n },\n ]\n },\n }\n}\n\ntype BundlePluginOptions = {\n /** Entry file for the bundle */\n entry: string\n /** Output file name */\n outputFile: string\n}\n\nfunction createBundlePlugin(pluginName: string, defaults: BundlePluginOptions) {\n return (options: Partial<BundlePluginOptions> = {}): Plugin => {\n const { entry, outputFile } = { ...defaults, ...options }\n return {\n name: pluginName,\n apply: \"build\",\n async closeBundle() {\n try {\n await build({\n configFile: false,\n logLevel: \"warn\",\n build: {\n lib: {\n entry: path.isAbsolute(entry) ? entry : path.resolve(process.cwd(), entry),\n formats: [\"es\"],\n fileName: () => outputFile,\n },\n outDir: \"dist\",\n emptyOutDir: false,\n },\n })\n } catch (error) {\n console.error(`[${pluginName}] build failed:`, error)\n throw error\n }\n },\n }\n }\n}\n\nexport type AppBundlePluginOptions = Partial<BundlePluginOptions>\n\n/**\n * Vite plugin that produces dist/app-bundle.js after the main build for app-level integrations.\n *\n * The bundle exports `renderThumbnail(puzzleStr, inputStr?, config?)` — a pure\n * SVG-string renderer used by the Puzzmo platform for puzzle previews.\n */\nexport const appBundlePlugin = createBundlePlugin(\"app-bundle\", { entry: \"src/appBundle.js\", outputFile: \"app-bundle.js\" })\n\nexport type EditorBundlePluginOptions = Partial<BundlePluginOptions>\n\n/** Vite plugin that produces dist/editor-bundle.js after the main build for editor-level integrations. */\nexport const editorBundlePlugin = createBundlePlugin(\"editor-bundle\", { entry: \"src/editorBundle.js\", outputFile: \"editor-bundle.js\" })\n\n/** Recursively find directories containing puzzmo.json, up to `maxDepth` levels deep. */\nexport const findPuzzmoJsonDirs = (root: string, maxDepth: number, depth = 0): string[] => {\n if (depth >= maxDepth) return []\n const results: string[] = []\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(root, { withFileTypes: true })\n } catch {\n return results\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue\n const dir = path.join(root, entry.name)\n if (fs.existsSync(path.join(dir, \"puzzmo.json\"))) {\n results.push(dir)\n }\n results.push(...findPuzzmoJsonDirs(dir, maxDepth, depth + 1))\n }\n return results\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite.js","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from \"vite\"\nimport { build } from \"vite\"\nimport path from \"path\"\nimport fs from \"fs\"\n\nexport type PuzzmoSimulatorPluginOptions = {\n /** Whether to auto-start the game after READY (default: true) */\n autoStart?: boolean\n /** Initial collapsed state (default: true) */\n collapsed?: boolean\n /**\n * Glob pattern for fixture files, passed to import.meta.glob which is relative to the closest puzzmo.json. Defaults to\n * `\"/fixtures/puzzles/**\\/*.json\"`. Pass false to disable.\n */\n fixturesGlob?: string | false\n}\n\nconst simulatorURL = \"/@puzzmo-simulator-init.js\"\nconst virtualID = \"virtual:puzzmo-simulator\"\n\n/** @internal */\nexport type GameInfo = {\n /** Directory containing the puzzmo.json */\n dir: string\n slug: string\n displayName: string\n /** Vite-root-relative path to app bundle entry, if it exists */\n appBundlePath: string | null\n}\n\n/**\n * Discover all games from puzzmo.json files under a root directory.\n *\n * @internal\n */\nexport function discoverGames(viteRoot: string): Map<string, GameInfo> {\n const games = new Map<string, GameInfo>()\n const candidates = findPuzzmoJsonDirs(viteRoot, 3)\n if (fs.existsSync(path.join(viteRoot, \"puzzmo.json\"))) {\n candidates.unshift(viteRoot)\n }\n for (const dir of candidates) {\n try {\n const data = JSON.parse(fs.readFileSync(path.join(dir, \"puzzmo.json\"), \"utf-8\"))\n if (!data?.game?.slug) continue\n const bundleEntry = path.join(dir, \"src\", \"appBundle.js\")\n let appBundle: string | null = null\n if (fs.existsSync(bundleEntry)) {\n const relative = path.relative(viteRoot, bundleEntry)\n appBundle = \"/\" + relative.split(path.sep).join(\"/\")\n }\n games.set(data.game.slug, { dir, slug: data.game.slug, displayName: data.game.displayName, appBundlePath: appBundle })\n } catch {\n // skip invalid files\n }\n }\n return games\n}\n\n/**\n * Resolve which game a request belongs to using the referer URL.\n *\n * @internal\n */\nexport function resolveGameFromReferer(referer: string | undefined, games: Map<string, GameInfo>, viteRoot: string): GameInfo | undefined {\n if (referer) {\n try {\n const refPath = new URL(referer).pathname\n for (const g of games.values()) {\n const relDir = \"/\" + path.relative(viteRoot, g.dir).split(path.sep).join(\"/\")\n if (refPath.startsWith(relDir + \"/\") || refPath === relDir) return g\n }\n } catch {\n // ignore malformed referer\n }\n }\n if (games.size === 1) return games.values().next().value\n return undefined\n}\n\n/**\n * Generate the virtual module code for the simulator.\n *\n * @internal\n */\nexport function generateSimulatorCode(options: PuzzmoSimulatorPluginOptions, game: GameInfo | undefined): string {\n const { fixturesGlob: fixturesOpt, ...config } = options\n const fixturesGlob = fixturesOpt === false ? null : (fixturesOpt ?? \"/fixtures/puzzles/**/*.json\")\n\n const lines = [`import { createSimulator } from \"@puzzmo/sdk/simulator\"`]\n\n if (fixturesGlob) {\n lines.push(`const fixtures = import.meta.glob(${JSON.stringify(fixturesGlob)}, { eager: true })`)\n }\n\n if (game?.appBundlePath) {\n lines.push(`import(${JSON.stringify(game.appBundlePath)}).then(m => {`)\n lines.push(` if (m.renderThumbnail) globalThis.renderThumbnail = m.renderThumbnail`)\n lines.push(`}).catch(() => {})`)\n }\n\n const simConfig = { ...config, ...(game?.slug ? { slug: game.slug } : {}) }\n const configEntries = Object.entries(simConfig).filter(([, v]) => v !== undefined)\n const configParts = configEntries.map(([k, v]) => `${k}: ${JSON.stringify(v)}`)\n if (fixturesGlob) configParts.push(\"fixtures\")\n\n lines.push(`createSimulator({ ${configParts.join(\", \")} })`)\n\n return lines.join(\"\\n\")\n}\n\n/** Vite plugin that injects the Puzzmo simulator in dev mode and handles OAuth callbacks. */\nexport function puzzmoSimulator(options: PuzzmoSimulatorPluginOptions = {}): Plugin {\n let games = new Map<string, GameInfo>()\n let viteRoot: string\n\n return {\n name: \"puzzmo-simulator\",\n apply: \"serve\",\n\n configResolved(config: ResolvedConfig) {\n viteRoot = config.root\n games = discoverGames(viteRoot)\n\n if (games.size === 0) {\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m\\x1b[2m no puzzmo.json files found\\x1b[22m`)\n } else {\n const names = [...games.values()].map((g) => `\\x1b[36m${g.slug}\\x1b[39m`)\n const label = games.size === 1 ? \"game\" : \"games\"\n config.logger.info(`\\x1b[33m\\x1b[1m PUZZMO \\x1b[22m\\x1b[39m found ${games.size} ${label}: ${names.join(\"\\x1b[2m, \\x1b[22m\")}`)\n }\n },\n\n resolveId(id) {\n if (id === virtualID || id.startsWith(virtualID + \"?\")) return \"\\0\" + id\n },\n\n load(id) {\n if (!id.startsWith(\"\\0\" + virtualID)) return\n const params = new URLSearchParams(id.split(\"?\")[1] || \"\")\n const gameSlug = params.get(\"game\")\n const game = gameSlug ? games.get(gameSlug) : games.size === 1 ? games.values().next().value : undefined\n return generateSimulatorCode(options, game)\n },\n\n configureServer(server) {\n server.middlewares.use(\"/oauth/callback\", (_req, res) => {\n res.setHeader(\"Content-Type\", \"text/html\")\n res.end(`<!DOCTYPE html>\n<html><head><title>Puzzmo OAuth</title></head>\n<body><script>\nvar params = new URLSearchParams(window.location.search);\nvar returnUrl = sessionStorage.getItem(\"oauth_return_url\") || \"/\";\nvar url = new URL(returnUrl);\nparams.forEach(function(v, k) { url.searchParams.set(k, v); });\nwindow.location.href = url.toString();\n</script></body></html>`)\n })\n\n // Serve the simulator init module, resolving the game from the referer\n server.middlewares.use(async (req, res, next) => {\n if (req.url?.split(\"?\")[0] !== simulatorURL) return next()\n\n const game = resolveGameFromReferer(req.headers.referer, games, viteRoot)\n const moduleID = virtualID + (game ? `?game=${game.slug}` : \"\")\n const result = await server.transformRequest(moduleID)\n if (!result) return next()\n res.setHeader(\"Content-Type\", \"application/javascript\")\n res.end(result.code)\n })\n },\n\n transformIndexHtml() {\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\", src: simulatorURL },\n injectTo: \"head\",\n },\n ]\n },\n }\n}\n\ntype BundlePluginOptions = {\n /** Entry file for the bundle */\n entry: string\n /** Output file name */\n outputFile: string\n}\n\nfunction createBundlePlugin(pluginName: string, defaults: BundlePluginOptions) {\n return (options: Partial<BundlePluginOptions> = {}): Plugin => {\n const { entry, outputFile } = { ...defaults, ...options }\n return {\n name: pluginName,\n apply: \"build\",\n async closeBundle() {\n try {\n await build({\n configFile: false,\n logLevel: \"warn\",\n build: {\n lib: {\n entry: path.isAbsolute(entry) ? entry : path.resolve(process.cwd(), entry),\n formats: [\"es\"],\n fileName: () => outputFile,\n },\n outDir: \"dist\",\n emptyOutDir: false,\n },\n })\n } catch (error) {\n console.error(`[${pluginName}] build failed:`, error)\n throw error\n }\n },\n }\n }\n}\n\nexport type AppBundlePluginOptions = Partial<BundlePluginOptions>\n\n/**\n * Vite plugin that produces dist/app-bundle.js after the main build for app-level integrations.\n *\n * The bundle exports `renderThumbnail(puzzleStr, inputStr?, config?)` — a pure\n * SVG-string renderer used by the Puzzmo platform for puzzle previews.\n */\nexport const appBundlePlugin = createBundlePlugin(\"app-bundle\", { entry: \"src/appBundle.js\", outputFile: \"app-bundle.js\" })\n\nexport type EditorBundlePluginOptions = Partial<BundlePluginOptions>\n\n/** Vite plugin that produces dist/editor-bundle.js after the main build for editor-level integrations. */\nexport const editorBundlePlugin = createBundlePlugin(\"editor-bundle\", { entry: \"src/editorBundle.js\", outputFile: \"editor-bundle.js\" })\n\n/**\n * Recursively find directories containing puzzmo.json, up to `maxDepth` levels deep.\n *\n * @internal\n */\nexport const findPuzzmoJsonDirs = (root: string, maxDepth: number, depth = 0): string[] => {\n if (depth >= maxDepth) return []\n const results: string[] = []\n let entries: fs.Dirent[]\n try {\n entries = fs.readdirSync(root, { withFileTypes: true })\n } catch {\n return results\n }\n for (const entry of entries) {\n if (!entry.isDirectory() || entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue\n const dir = path.join(root, entry.name)\n if (fs.existsSync(path.join(dir, \"puzzmo.json\"))) {\n results.push(dir)\n }\n results.push(...findPuzzmoJsonDirs(dir, maxDepth, depth + 1))\n }\n return results\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;SAsFU,eAAA,EArEJ,IAAe,8BACf,IAAY;;;;;;AAiBlB,SAAgB,EAAc,GAAyC;CACrE,IAAM,oBAAQ,IAAI,KAAuB,EACnC,IAAa,EAAmB,GAAU,EAAE;AAClD,CAAI,EAAG,WAAW,EAAK,KAAK,GAAU,cAAc,CAAC,IACnD,EAAW,QAAQ,EAAS;AAE9B,MAAK,IAAM,KAAO,EAChB,KAAI;;EACF,IAAM,IAAO,KAAK,MAAM,EAAG,aAAa,EAAK,KAAK,GAAK,cAAc,EAAE,QAAQ,CAAC;AAChF,MAAI,EAAA,OAAA,SAAA,IAAC,EAAM,SAAA,SAAA,EAAM,MAAM;EACvB,IAAM,IAAc,EAAK,KAAK,GAAK,OAAO,eAAe,EACrD,IAA2B;AAK/B,EAJI,EAAG,WAAW,EAAY,KAE5B,IAAY,MADK,EAAK,SAAS,GAAU,EAAY,CAC1B,MAAM,EAAK,IAAI,CAAC,KAAK,IAAI,GAEtD,EAAM,IAAI,EAAK,KAAK,MAAM;GAAE;GAAK,MAAM,EAAK,KAAK;GAAM,aAAa,EAAK,KAAK;GAAa,eAAe;GAAW,CAAC;aAChH;AAIV,QAAO;;;;;;;AAQT,SAAgB,EAAuB,GAA6B,GAA8B,GAAwC;AACxI,KAAI,EACF,KAAI;EACF,IAAM,IAAU,IAAI,IAAI,EAAQ,CAAC;AACjC,OAAK,IAAM,KAAK,EAAM,QAAQ,EAAE;GAC9B,IAAM,IAAS,MAAM,EAAK,SAAS,GAAU,EAAE,IAAI,CAAC,MAAM,EAAK,IAAI,CAAC,KAAK,IAAI;AAC7E,OAAI,EAAQ,WAAW,IAAS,IAAI,IAAI,MAAY,EAAQ,QAAO;;aAE/D;AAIV,KAAI,EAAM,SAAS,EAAG,QAAO,EAAM,QAAQ,CAAC,MAAM,CAAC;;;;;;;AASrD,SAAgB,EAAsB,GAAuC,GAAoC;CAC/G,IAAM,EAAE,cAAc,MAAA,GAAgB,IAAA,EAAW,GAAA,EAAA,EAC3C,IAAe,MAAgB,KAAQ,OAAQ,KAAA,OAAe,gCAAf,GAE/C,IAAQ,CAAC,4DAA0D;AAMzE,CAJI,KACF,EAAM,KAAK,qCAAqC,KAAK,UAAU,EAAa,CAAC,oBAAoB,EAGnG,KAAA,QAAI,EAAM,kBACR,EAAM,KAAK,UAAU,KAAK,UAAU,EAAK,cAAc,CAAC,eAAe,EACvE,EAAM,KAAK,0EAA0E,EACrF,EAAM,KAAK,qBAAqB;CAGlC,IAAM,IAAA,EAAA,EAAA,EAAA,EAAiB,EAAA,EAAA,KAAA,QAAY,EAAM,OAAO,EAAE,MAAM,EAAK,MAAM,GAAG,EAAE,CAAG,EAErE,IADgB,OAAO,QAAQ,EAAU,CAAC,QAAQ,GAAG,OAAO,MAAM,KAAA,EAAU,CAChD,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,IAAI,KAAK,UAAU,EAAE,GAAG;AAK/E,QAJI,KAAc,EAAY,KAAK,WAAW,EAE9C,EAAM,KAAK,qBAAqB,EAAY,KAAK,KAAK,CAAC,KAAK,EAErD,EAAM,KAAK,KAAK;;;AAIzB,SAAgB,EAAgB,IAAwC,EAAE,EAAU;CAClF,IAAI,oBAAQ,IAAI,KAAuB,EACnC;AAEJ,QAAO;EACL,MAAM;EACN,OAAO;EAEP,eAAe,GAAwB;AAIrC,OAHA,IAAW,EAAO,MAClB,IAAQ,EAAc,EAAS,EAE3B,EAAM,SAAS,EACjB,GAAO,OAAO,KAAK,qFAAqF;QACnG;IACL,IAAM,IAAQ,CAAC,GAAG,EAAM,QAAQ,CAAC,CAAC,KAAK,MAAM,WAAW,EAAE,KAAK,UAAU,EACnE,IAAQ,EAAM,SAAS,IAAI,SAAS;AAC1C,MAAO,OAAO,KAAK,kDAAkD,EAAM,KAAK,GAAG,EAAM,IAAI,EAAM,KAAK,oBAAoB,GAAG;;;EAInI,UAAU,GAAI;AACZ,OAAI,MAAO,KAAa,EAAG,WAAW,IAAY,IAAI,CAAE,QAAO,OAAO;;EAGxE,KAAK,GAAI;AACP,OAAI,CAAC,EAAG,WAAW,OAAO,EAAU,CAAE;GAEtC,IAAM,IADS,IAAI,gBAAgB,EAAG,MAAM,IAAI,CAAC,MAAM,GAAG,CAClC,IAAI,OAAO;AAEnC,UAAO,EAAsB,GADhB,IAAW,EAAM,IAAI,EAAS,GAAG,EAAM,SAAS,IAAI,EAAM,QAAQ,CAAC,MAAM,CAAC,QAAQ,KAAA,EACpD;;EAG7C,gBAAgB,GAAQ;AAetB,GAdA,EAAO,YAAY,IAAI,oBAAoB,GAAM,MAAQ;AAEvD,IADA,EAAI,UAAU,gBAAgB,YAAY,EAC1C,EAAI,IAAI,uXAQS;KACjB,EAGF,EAAO,YAAY,IAAA,WAAA;yBAAW,GAAK,GAAK,GAAS;;AAC/C,WAAA,IAAI,EAAI,QAAA,OAAA,KAAA,IAAA,EAAK,MAAM,IAAI,CAAC,QAAO,EAAc,QAAO,GAAM;KAE1D,IAAM,IAAO,EAAuB,EAAI,QAAQ,SAAS,GAAO,EAAS,EACnE,IAAW,KAAa,IAAO,SAAS,EAAK,SAAS,KACtD,IAAS,MAAM,EAAO,iBAAiB,EAAS;AACtD,SAAI,CAAC,EAAQ,QAAO,GAAM;AAE1B,KADA,EAAI,UAAU,gBAAgB,yBAAyB,EACvD,EAAI,IAAI,EAAO,KAAK;;oBARQ,GAAK,GAAK,GAAA;;;OAStC;;EAGJ,qBAAqB;AACnB,UAAO,CACL;IACE,KAAK;IACL,OAAO;KAAE,MAAM;KAAU,KAAK;KAAc;IAC5C,UAAU;IACX,CACF;;EAEJ;;AAUH,SAAS,EAAmB,GAAoB,GAA+B;AAC7E,SAAQ,IAAwC,EAAE,KAAa;EAC7D,IAAM,EAAE,UAAO,kBAAA,EAAA,EAAA,EAAA,EAAoB,EAAA,EAAa,EAAS;AACzD,SAAO;GACL,MAAM;GACN,OAAO;GACP,cAAM;0BAAc;AAClB,SAAI;AACF,YAAM,EAAM;OACV,YAAY;OACZ,UAAU;OACV,OAAO;QACL,KAAK;SACH,OAAO,EAAK,WAAW,EAAM,GAAG,IAAQ,EAAK,QAAQ,QAAQ,KAAK,EAAE,EAAM;SAC1E,SAAS,CAAC,KAAK;SACf,gBAAgB;SACjB;QACD,QAAQ;QACR,aAAa;QACd;OACF,CAAC;cACK,GAAO;AAEd,YADA,QAAQ,MAAM,IAAI,EAAW,kBAAkB,EAAM,EAC/C;;;;GAGX;;;;;;;;;AAYL,MAAa,IAAkB,EAAmB,cAAc;CAAE,OAAO;CAAoB,YAAY;CAAiB,CAAC,EAK9G,IAAqB,EAAmB,iBAAiB;CAAE,OAAO;CAAuB,YAAY;CAAoB,CAAC,EAO1H,KAAsB,GAAc,GAAkB,IAAQ,MAAgB;AACzF,KAAI,KAAS,EAAU,QAAO,EAAE;CAChC,IAAM,IAAoB,EAAE,EACxB;AACJ,KAAI;AACF,MAAU,EAAG,YAAY,GAAM,EAAE,eAAe,IAAM,CAAC;aACjD;AACN,SAAO;;AAET,MAAK,IAAM,KAAS,GAAS;AAC3B,MAAI,CAAC,EAAM,aAAa,IAAI,EAAM,KAAK,WAAW,IAAI,IAAI,EAAM,SAAS,eAAgB;EACzF,IAAM,IAAM,EAAK,KAAK,GAAM,EAAM,KAAK;AAIvC,EAHI,EAAG,WAAW,EAAK,KAAK,GAAK,cAAc,CAAC,IAC9C,EAAQ,KAAK,EAAI,EAEnB,EAAQ,KAAK,GAAG,EAAmB,GAAK,GAAU,IAAQ,EAAE,CAAC;;AAE/D,QAAO"}
|