@playcademy/vite-plugin 0.0.1-beta.2 → 0.0.1-beta.5

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.
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Manifest generation and build output functionality
3
+ */
4
+ import type { ResolvedConfig } from 'vite';
5
+ import type { ManifestV1 } from '@playcademy/types';
6
+ export interface PlaycademyOutputData {
7
+ manifestPath?: string;
8
+ manifestSizeKb?: string;
9
+ zipPath?: string;
10
+ zipSizeKb?: string;
11
+ }
12
+ export interface ManifestOptions {
13
+ bootMode: ManifestV1['bootMode'];
14
+ entryPoint: string;
15
+ styles: string[];
16
+ platform: ManifestV1['platform'];
17
+ }
18
+ export declare function generatePlaycademyManifest(config: ResolvedConfig, options: ManifestOptions, outDir: string, buildOutputs: PlaycademyOutputData): Promise<void>;
19
+ export declare function createOutputZipArchive(config: ResolvedConfig, outDir: string, buildOutputs: PlaycademyOutputData): Promise<void>;
20
+ export declare function performPlaycademyLogging(config: ResolvedConfig, buildOutputs: PlaycademyOutputData): void;
@@ -0,0 +1,9 @@
1
+ import { type ProjectInfo } from '../utils';
2
+ import type { ResolvedConfig } from 'vite';
3
+ interface SandboxManager {
4
+ url: string;
5
+ project: ProjectInfo | null;
6
+ cleanup: () => void;
7
+ }
8
+ export declare function startSandbox(viteConfig: ResolvedConfig, autoStart?: boolean, verbose?: boolean): Promise<SandboxManager>;
9
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { ViteDevServer } from 'vite';
2
+ import type { ProjectInfo } from '../utils';
3
+ export declare function devServerMiddleware(server: ViteDevServer, sandboxUrl: string, project: ProjectInfo): void;
Binary file
Binary file
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Utility functions for the Playcademy Vite plugin
3
+ */
4
+ import type { ResolvedConfig } from 'vite';
5
+ export interface ProjectInfo {
6
+ slug: string;
7
+ displayName: string;
8
+ version: string;
9
+ description?: string;
10
+ }
11
+ export declare function extractProjectInfo(viteConfig: ResolvedConfig): ProjectInfo;
12
+ export declare function formatNumberWithCommas(numStr: string): string;
13
+ export declare function findAvailablePort(startPort?: number): Promise<number>;
package/package.json CHANGED
@@ -1,19 +1,25 @@
1
1
  {
2
2
  "name": "@playcademy/vite-plugin",
3
3
  "type": "module",
4
- "version": "0.0.1-beta.2",
5
- "module": "src/index.ts",
4
+ "version": "0.0.1-beta.5",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.js",
6
7
  "exports": {
7
8
  ".": {
8
9
  "import": "./dist/index.js",
9
10
  "types": "./dist/index.d.ts"
10
11
  }
11
12
  },
13
+ "files": [
14
+ "dist"
15
+ ],
12
16
  "scripts": {
13
- "build": "bun build.ts",
14
- "pub": "bun run build && bunx bumpp --no-tag --no-push -m \"chore(@playcademy/vite-plugin): release v{version}\" && bun publish --access public"
17
+ "build": "rm -rf dist && bun build.ts",
18
+ "bump": "bunx bumpp --no-tag --no-push -c \"chore(@playcademy/vite-plugin): release v%s\"",
19
+ "pub": "bun run build && bun run bump && bun publish --access public"
15
20
  },
16
21
  "devDependencies": {
22
+ "@playcademy/sandbox": "0.1.0-beta.2",
17
23
  "@playcademy/types": "latest",
18
24
  "@types/archiver": "^6.0.3",
19
25
  "@types/bun": "latest"
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
@@ -1,9 +0,0 @@
1
- /* This file is auto-generated by SST. Do not edit. */
2
- /* tslint:disable */
3
- /* eslint-disable */
4
- /* deno-fmt-ignore-file */
5
-
6
- /// <reference path="../../sst-env.d.ts" />
7
-
8
- import "sst"
9
- export {}
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
- }
@@ -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
- }