@playcademy/vite-plugin 0.0.1-beta.2 → 0.0.1-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +289 -49
- package/dist/index.d.ts +11 -0
- package/dist/index.js +121536 -0
- package/dist/lib/manifest.d.ts +8 -0
- package/dist/lib/sandbox.d.ts +3 -0
- package/dist/lib/server.d.ts +3 -0
- package/dist/pglite.data +0 -0
- package/dist/pglite.wasm +0 -0
- package/dist/types.d.ts +65 -0
- package/dist/types.js +0 -0
- package/dist/utils.d.ts +8 -0
- package/package.json +20 -10
- package/build.ts +0 -45
- package/src/index.ts +0 -219
- package/sst-env.d.ts +0 -9
- package/tsconfig.json +0 -28
- package/tsconfig.types.json +0 -13
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manifest generation and build output functionality
|
|
3
|
+
*/
|
|
4
|
+
import type { ResolvedConfig } from 'vite';
|
|
5
|
+
import type { ManifestOptions, PlaycademyOutputData } from '../types';
|
|
6
|
+
export declare function generatePlaycademyManifest(config: ResolvedConfig, options: ManifestOptions, outDir: string, buildOutputs: PlaycademyOutputData): Promise<void>;
|
|
7
|
+
export declare function createOutputZipArchive(config: ResolvedConfig, outDir: string, buildOutputs: PlaycademyOutputData): Promise<void>;
|
|
8
|
+
export declare function performPlaycademyLogging(config: ResolvedConfig, buildOutputs: PlaycademyOutputData): void;
|
package/dist/pglite.data
ADDED
|
Binary file
|
package/dist/pglite.wasm
ADDED
|
Binary file
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the Playcademy Vite Plugin
|
|
3
|
+
*/
|
|
4
|
+
import type { ManifestV1 } from '@playcademy/data/types';
|
|
5
|
+
/**
|
|
6
|
+
* Project information extracted from package.json and directory structure
|
|
7
|
+
*/
|
|
8
|
+
export interface ProjectInfo {
|
|
9
|
+
slug: string;
|
|
10
|
+
displayName: string;
|
|
11
|
+
version: string;
|
|
12
|
+
description?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for exporting Playcademy games
|
|
16
|
+
*/
|
|
17
|
+
export interface PlaycademyExportOptions {
|
|
18
|
+
bootMode?: ManifestV1['bootMode'];
|
|
19
|
+
entryPoint?: string;
|
|
20
|
+
styles?: string[];
|
|
21
|
+
platform?: ManifestV1['platform'];
|
|
22
|
+
autoZip?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Configuration options for the Playcademy sandbox server
|
|
26
|
+
*/
|
|
27
|
+
export interface PlaycademySandboxOptions {
|
|
28
|
+
autoStart?: boolean;
|
|
29
|
+
url?: string;
|
|
30
|
+
verbose?: boolean;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Main plugin configuration options
|
|
34
|
+
*/
|
|
35
|
+
export interface PlaycademyPluginOptions {
|
|
36
|
+
export?: PlaycademyExportOptions;
|
|
37
|
+
sandbox?: PlaycademySandboxOptions;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Build output data for logging and tracking
|
|
41
|
+
*/
|
|
42
|
+
export interface PlaycademyOutputData {
|
|
43
|
+
manifestPath?: string;
|
|
44
|
+
manifestSizeKb?: string;
|
|
45
|
+
zipPath?: string;
|
|
46
|
+
zipSizeKb?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options for manifest generation
|
|
50
|
+
*/
|
|
51
|
+
export interface ManifestOptions {
|
|
52
|
+
bootMode: ManifestV1['bootMode'];
|
|
53
|
+
entryPoint: string;
|
|
54
|
+
styles: string[];
|
|
55
|
+
platform: ManifestV1['platform'];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Sandbox manager interface for controlling sandbox lifecycle
|
|
59
|
+
*/
|
|
60
|
+
export interface SandboxManager {
|
|
61
|
+
baseUrl: string;
|
|
62
|
+
realtimeUrl: string;
|
|
63
|
+
project: ProjectInfo | null;
|
|
64
|
+
cleanup: () => void;
|
|
65
|
+
}
|
package/dist/types.js
ADDED
|
File without changes
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for the Playcademy Vite plugin
|
|
3
|
+
*/
|
|
4
|
+
import type { ResolvedConfig } from 'vite';
|
|
5
|
+
import type { ProjectInfo } from './types';
|
|
6
|
+
export declare function extractProjectInfo(viteConfig: ResolvedConfig): ProjectInfo;
|
|
7
|
+
export declare function formatNumberWithCommas(numStr: string): string;
|
|
8
|
+
export declare function findAvailablePort(startPort?: number): Promise<number>;
|
package/package.json
CHANGED
|
@@ -1,28 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playcademy/vite-plugin",
|
|
3
|
+
"version": "0.0.1-beta.20",
|
|
3
4
|
"type": "module",
|
|
4
|
-
"version": "0.0.1-beta.2",
|
|
5
|
-
"module": "src/index.ts",
|
|
6
5
|
"exports": {
|
|
7
6
|
".": {
|
|
8
7
|
"import": "./dist/index.js",
|
|
9
8
|
"types": "./dist/index.d.ts"
|
|
9
|
+
},
|
|
10
|
+
"./types": {
|
|
11
|
+
"import": "./dist/types.js",
|
|
12
|
+
"types": "./dist/types.d.ts"
|
|
10
13
|
}
|
|
11
14
|
},
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"module": "dist/index.js",
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
12
20
|
"scripts": {
|
|
13
|
-
"build": "bun build.ts",
|
|
14
|
-
"
|
|
21
|
+
"build": "rm -rf dist && bun build.ts",
|
|
22
|
+
"bump": "SKIP_TESTS=1 bunx bumpp --no-tag --no-push -c \"chore(@playcademy/vite-plugin): release v%s\"",
|
|
23
|
+
"pub": "bun run build && bun run bump && bun publish --access public"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"archiver": "^7.0.1",
|
|
27
|
+
"picocolors": "^1.1.1"
|
|
15
28
|
},
|
|
16
29
|
"devDependencies": {
|
|
17
|
-
"@playcademy/
|
|
30
|
+
"@playcademy/sandbox": "0.1.0-beta.14",
|
|
18
31
|
"@types/archiver": "^6.0.3",
|
|
19
|
-
"@types/bun": "latest"
|
|
32
|
+
"@types/bun": "latest",
|
|
33
|
+
"yocto-spinner": "^0.2.2"
|
|
20
34
|
},
|
|
21
35
|
"peerDependencies": {
|
|
22
36
|
"typescript": "^5"
|
|
23
|
-
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"archiver": "^7.0.1",
|
|
26
|
-
"picocolors": "^1.1.1"
|
|
27
37
|
}
|
|
28
38
|
}
|
package/build.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { $ } from 'bun'
|
|
2
|
-
import packageJson from './package.json' assert { type: 'json' }
|
|
3
|
-
import yoctoSpinner from 'yocto-spinner'
|
|
4
|
-
|
|
5
|
-
const startTime = performance.now()
|
|
6
|
-
const spinner = yoctoSpinner({ text: 'Building JavaScript...' }).start()
|
|
7
|
-
|
|
8
|
-
const buildDir = './dist'
|
|
9
|
-
const entrypoints = ['./src/index.ts']
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
await $`rm -rf ${buildDir}`
|
|
13
|
-
|
|
14
|
-
await Bun.build({
|
|
15
|
-
entrypoints,
|
|
16
|
-
external: [...Object.keys(packageJson.peerDependencies)],
|
|
17
|
-
outdir: buildDir,
|
|
18
|
-
format: 'esm',
|
|
19
|
-
target: 'node',
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
spinner.text = 'Generating types...'
|
|
23
|
-
|
|
24
|
-
const { stderr } =
|
|
25
|
-
await $`tsc --emitDeclarationOnly --declaration --project tsconfig.types.json --outDir ${buildDir}`
|
|
26
|
-
|
|
27
|
-
if (stderr.toString().length) {
|
|
28
|
-
spinner.error(`Type generation failed:\n${stderr.toString()}`)
|
|
29
|
-
process.exit(1) // Exit with error code
|
|
30
|
-
} else {
|
|
31
|
-
const duration = ((performance.now() - startTime) / 1000).toFixed(2)
|
|
32
|
-
spinner.success(`Build complete in ${duration}s!`)
|
|
33
|
-
|
|
34
|
-
// Log built entrypoints
|
|
35
|
-
for (const entry of entrypoints) {
|
|
36
|
-
console.log(` - ${entry}`)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
process.exit(0)
|
|
40
|
-
} catch (error) {
|
|
41
|
-
const duration = ((performance.now() - startTime) / 1000).toFixed(2)
|
|
42
|
-
console.log({ error })
|
|
43
|
-
spinner.error(`Build failed in ${duration}s: ${error}`)
|
|
44
|
-
process.exit(1) // Exit with error code
|
|
45
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import path from 'node:path'
|
|
2
|
-
import fs from 'node:fs/promises'
|
|
3
|
-
import { createWriteStream } from 'node:fs'
|
|
4
|
-
import archiver from 'archiver'
|
|
5
|
-
import pc from 'picocolors'
|
|
6
|
-
|
|
7
|
-
import type { Plugin, ResolvedConfig } from 'vite'
|
|
8
|
-
import type { ManifestV1 } from '@playcademy/types'
|
|
9
|
-
|
|
10
|
-
export interface PlaycademyPluginOptions {
|
|
11
|
-
bootMode?: ManifestV1['bootMode']
|
|
12
|
-
entryPoint?: string
|
|
13
|
-
styles?: string[]
|
|
14
|
-
engine?: ManifestV1['engine']
|
|
15
|
-
autoZip?: boolean
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const LOG_LINE_TOTAL_WIDTH = 60
|
|
19
|
-
|
|
20
|
-
interface PlaycademyOutputData {
|
|
21
|
-
manifestPath?: string
|
|
22
|
-
manifestSizeKb?: string
|
|
23
|
-
zipPath?: string
|
|
24
|
-
zipSizeKb?: string
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function formatNumberWithCommas(numStr: string): string {
|
|
28
|
-
if (!numStr) return numStr
|
|
29
|
-
const parts = numStr.split('.')
|
|
30
|
-
if (parts[0] === undefined) return numStr
|
|
31
|
-
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',')
|
|
32
|
-
return parts.join('.')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
async function generatePlaycademyManifest(
|
|
36
|
-
config: ResolvedConfig,
|
|
37
|
-
options: Required<Omit<PlaycademyPluginOptions, 'autoZip'>>,
|
|
38
|
-
outDir: string,
|
|
39
|
-
buildOutputs: PlaycademyOutputData,
|
|
40
|
-
) {
|
|
41
|
-
const manifestData: ManifestV1 = {
|
|
42
|
-
version: '1',
|
|
43
|
-
bootMode: options.bootMode,
|
|
44
|
-
entryPoint: options.entryPoint,
|
|
45
|
-
styles: options.styles || [],
|
|
46
|
-
engine: options.engine || 'custom',
|
|
47
|
-
createdAt: new Date().toISOString(),
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const manifestPath = path.resolve(outDir, 'playcademy.manifest.json')
|
|
51
|
-
const manifestJson = JSON.stringify(manifestData, null, 2)
|
|
52
|
-
|
|
53
|
-
await fs.writeFile(manifestPath, manifestJson)
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
const stats = await fs.stat(manifestPath)
|
|
57
|
-
buildOutputs.manifestPath = path.relative(config.root, manifestPath)
|
|
58
|
-
buildOutputs.manifestSizeKb = (stats.size / 1024).toFixed(2)
|
|
59
|
-
} catch (statError) {
|
|
60
|
-
config.logger.warn(
|
|
61
|
-
`[Playcademy] Could not get stats for manifest file: ${statError}`,
|
|
62
|
-
)
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
async function createOutputZipArchive(
|
|
67
|
-
config: ResolvedConfig,
|
|
68
|
-
outDir: string,
|
|
69
|
-
buildOutputs: PlaycademyOutputData,
|
|
70
|
-
) {
|
|
71
|
-
const projectRoot = path.resolve(config.root)
|
|
72
|
-
const projectName = path.basename(projectRoot)
|
|
73
|
-
const playcademyDir = path.resolve(projectRoot, '.playcademy')
|
|
74
|
-
|
|
75
|
-
await fs.mkdir(playcademyDir, { recursive: true })
|
|
76
|
-
|
|
77
|
-
const zipName = `${projectName}.zip`
|
|
78
|
-
const zipOutPath = path.resolve(playcademyDir, zipName)
|
|
79
|
-
|
|
80
|
-
const output = createWriteStream(zipOutPath)
|
|
81
|
-
const archive = archiver('zip', {
|
|
82
|
-
zlib: { level: 9 },
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
await new Promise<void>((resolve, reject) => {
|
|
86
|
-
output.on('close', () => {
|
|
87
|
-
buildOutputs.zipPath = path.relative(config.root, zipOutPath)
|
|
88
|
-
buildOutputs.zipSizeKb = (archive.pointer() / 1024).toFixed(2)
|
|
89
|
-
resolve()
|
|
90
|
-
})
|
|
91
|
-
output.on('error', reject)
|
|
92
|
-
archive.pipe(output)
|
|
93
|
-
archive.directory(outDir, false)
|
|
94
|
-
archive.finalize()
|
|
95
|
-
})
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function performPlaycademyLogging(
|
|
99
|
-
config: ResolvedConfig,
|
|
100
|
-
buildOutputs: PlaycademyOutputData,
|
|
101
|
-
) {
|
|
102
|
-
if (!buildOutputs.manifestPath && !buildOutputs.zipSizeKb) {
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
config.logger.info('') // newline
|
|
107
|
-
config.logger.info(pc.magenta('[Playcademy]'))
|
|
108
|
-
|
|
109
|
-
if (buildOutputs.manifestPath && buildOutputs.manifestSizeKb) {
|
|
110
|
-
const dir = path.dirname(buildOutputs.manifestPath)
|
|
111
|
-
const file = path.basename(buildOutputs.manifestPath)
|
|
112
|
-
const uncoloredPathLength =
|
|
113
|
-
(dir === '.' ? 0 : dir.length + 1) + file.length
|
|
114
|
-
const coloredPath = `${pc.dim(dir === '.' ? '' : dir + '/')}${pc.green(file)}`
|
|
115
|
-
|
|
116
|
-
const formattedNumber = formatNumberWithCommas(
|
|
117
|
-
buildOutputs.manifestSizeKb!,
|
|
118
|
-
)
|
|
119
|
-
const sizeString = `${formattedNumber} kB`
|
|
120
|
-
const formattedSize = pc.bold(pc.yellow(sizeString))
|
|
121
|
-
|
|
122
|
-
const paddingNeeded = Math.max(
|
|
123
|
-
2,
|
|
124
|
-
LOG_LINE_TOTAL_WIDTH - uncoloredPathLength - sizeString.length,
|
|
125
|
-
)
|
|
126
|
-
const paddingSpaces = ' '.repeat(paddingNeeded)
|
|
127
|
-
|
|
128
|
-
config.logger.info(`${coloredPath}${paddingSpaces}${formattedSize}`)
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (buildOutputs.zipPath && buildOutputs.zipSizeKb) {
|
|
132
|
-
let dir = path.dirname(buildOutputs.zipPath)
|
|
133
|
-
const file = path.basename(buildOutputs.zipPath)
|
|
134
|
-
if (dir === '.') dir = ''
|
|
135
|
-
const uncoloredPathLength = (dir ? dir.length + 1 : 0) + file.length
|
|
136
|
-
const coloredPath = `${dir ? pc.dim(dir + '/') : ''}${pc.green(file)}`
|
|
137
|
-
|
|
138
|
-
const formattedNumber = formatNumberWithCommas(buildOutputs.zipSizeKb!)
|
|
139
|
-
const sizeString = `${formattedNumber} kB`
|
|
140
|
-
const formattedSize = pc.bold(pc.yellow(sizeString))
|
|
141
|
-
|
|
142
|
-
const paddingNeeded = Math.max(
|
|
143
|
-
2,
|
|
144
|
-
LOG_LINE_TOTAL_WIDTH - uncoloredPathLength - sizeString.length,
|
|
145
|
-
)
|
|
146
|
-
const paddingSpaces = ' '.repeat(paddingNeeded)
|
|
147
|
-
|
|
148
|
-
config.logger.info(`${coloredPath}${paddingSpaces}${formattedSize}`)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
config.logger.info('') // newline
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export function playcademy(options: PlaycademyPluginOptions = {}): Plugin {
|
|
155
|
-
let viteConfig: ResolvedConfig
|
|
156
|
-
let currentBuildOutputs: PlaycademyOutputData = {}
|
|
157
|
-
|
|
158
|
-
const finalOptions = {
|
|
159
|
-
bootMode: options.bootMode ?? 'iframe',
|
|
160
|
-
entryPoint: options.entryPoint ?? 'index.html',
|
|
161
|
-
styles: options.styles ?? [],
|
|
162
|
-
engine: options.engine ?? 'custom',
|
|
163
|
-
autoZip: process.env.CI === 'true' ? false : (options.autoZip ?? false),
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
name: 'vite-plugin-playcademy',
|
|
168
|
-
|
|
169
|
-
config(userConfig) {
|
|
170
|
-
if (userConfig.base === undefined) {
|
|
171
|
-
return {
|
|
172
|
-
base: './',
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
return {}
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
configResolved(resolvedConfig) {
|
|
179
|
-
viteConfig = resolvedConfig
|
|
180
|
-
currentBuildOutputs = {}
|
|
181
|
-
},
|
|
182
|
-
|
|
183
|
-
async writeBundle() {
|
|
184
|
-
const outDir =
|
|
185
|
-
viteConfig.build.outDir || path.join(process.cwd(), 'dist')
|
|
186
|
-
|
|
187
|
-
try {
|
|
188
|
-
await generatePlaycademyManifest(
|
|
189
|
-
viteConfig,
|
|
190
|
-
finalOptions,
|
|
191
|
-
outDir,
|
|
192
|
-
currentBuildOutputs,
|
|
193
|
-
)
|
|
194
|
-
if (finalOptions.autoZip) {
|
|
195
|
-
await createOutputZipArchive(
|
|
196
|
-
viteConfig,
|
|
197
|
-
outDir,
|
|
198
|
-
currentBuildOutputs,
|
|
199
|
-
)
|
|
200
|
-
}
|
|
201
|
-
} catch (error) {
|
|
202
|
-
if (
|
|
203
|
-
error instanceof Error &&
|
|
204
|
-
error.message.includes('[Playcademy]')
|
|
205
|
-
) {
|
|
206
|
-
viteConfig.logger.error(error.message)
|
|
207
|
-
} else {
|
|
208
|
-
viteConfig.logger.error(
|
|
209
|
-
`[Playcademy] An unexpected error occurred during writeBundle: ${error instanceof Error ? error.message : String(error)}`,
|
|
210
|
-
)
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
closeBundle() {
|
|
216
|
-
performPlaycademyLogging(viteConfig, currentBuildOutputs)
|
|
217
|
-
},
|
|
218
|
-
}
|
|
219
|
-
}
|
package/sst-env.d.ts
DELETED
package/tsconfig.json
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
// Environment setup & latest features
|
|
4
|
-
"lib": ["ESNext"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "ESNext",
|
|
7
|
-
"moduleDetection": "force",
|
|
8
|
-
"jsx": "react-jsx",
|
|
9
|
-
"allowJs": true,
|
|
10
|
-
|
|
11
|
-
// Bundler mode
|
|
12
|
-
"moduleResolution": "bundler",
|
|
13
|
-
"allowImportingTsExtensions": true,
|
|
14
|
-
"verbatimModuleSyntax": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
|
|
17
|
-
// Best practices
|
|
18
|
-
"strict": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"noFallthroughCasesInSwitch": true,
|
|
21
|
-
"noUncheckedIndexedAccess": true,
|
|
22
|
-
|
|
23
|
-
// Some stricter flags (disabled by default)
|
|
24
|
-
"noUnusedLocals": false,
|
|
25
|
-
"noUnusedParameters": false,
|
|
26
|
-
"noPropertyAccessFromIndexSignature": false
|
|
27
|
-
}
|
|
28
|
-
}
|
package/tsconfig.types.json
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"noEmit": false,
|
|
5
|
-
"emitDeclarationOnly": true,
|
|
6
|
-
"declaration": true,
|
|
7
|
-
"outDir": "./dist",
|
|
8
|
-
"rootDir": "./src",
|
|
9
|
-
"skipLibCheck": true
|
|
10
|
-
},
|
|
11
|
-
"include": ["src/**/*.ts"],
|
|
12
|
-
"exclude": ["node_modules", "**/*.test.ts"]
|
|
13
|
-
}
|