Skip to content

Commit 81aa2dd

Browse files
PlayBridgeJS: Setup basic structure for BridgeJS integration
1 parent 8945b52 commit 81aa2dd

19 files changed

+1266
-16
lines changed

Examples/PlayBridgeJS/Package.swift

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,33 @@ let package = Package(
77
platforms: [
88
.macOS(.v14)
99
],
10-
dependencies: [.package(name: "JavaScriptKit", path: "../../")],
10+
dependencies: [
11+
.package(name: "JavaScriptKit", path: "../../"),
12+
.package(url: "https://github.com/swiftlang/swift-syntax", from: "600.0.1")
13+
],
1114
targets: [
1215
.executableTarget(
1316
name: "PlayBridgeJS",
1417
dependencies: [
1518
"JavaScriptKit",
1619
.product(name: "JavaScriptEventLoop", package: "JavaScriptKit"),
20+
.product(name: "SwiftParser", package: "swift-syntax"),
21+
.product(name: "SwiftSyntax", package: "swift-syntax"),
22+
.product(name: "SwiftBasicFormat", package: "swift-syntax"),
23+
.product(name: "SwiftSyntaxBuilder", package: "swift-syntax"),
24+
],
25+
swiftSettings: [
26+
.enableExperimentalFeature("Extern"),
27+
],
28+
linkerSettings: [
29+
.unsafeFlags(
30+
[
31+
"-Xlinker", "--stack-first",
32+
"-Xlinker", "--global-base=524288",
33+
"-Xlinker", "-z", "-Xlinker", "stack-size=524288",
34+
],
35+
.when(platforms: [.wasi])
36+
)
1737
]
1838
)
1939
]
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
// BridgeJS Playground Main Application
2+
import { EditorSystem } from './editor.js';
3+
import ts from 'typescript';
4+
import { TypeProcessor } from './processor.js';
5+
6+
export class BridgeJSPlayground {
7+
constructor() {
8+
this.editorSystem = new EditorSystem();
9+
this.playBridgeJS = null;
10+
this.generateTimeout = null;
11+
this.isInitialized = false;
12+
13+
// DOM Elements
14+
this.errorDisplay = document.getElementById('errorDisplay');
15+
this.errorMessage = document.getElementById('errorMessage');
16+
}
17+
18+
// Initialize the application
19+
async initialize() {
20+
if (this.isInitialized) {
21+
return;
22+
}
23+
24+
try {
25+
// Initialize editor system
26+
await this.editorSystem.init();
27+
28+
// Initialize BridgeJS
29+
await this.initializeBridgeJS();
30+
31+
// Set up event listeners
32+
this.setupEventListeners();
33+
34+
// Load sample code
35+
this.editorSystem.loadSampleCode();
36+
37+
this.isInitialized = true;
38+
console.log('BridgeJS Playground initialized successfully');
39+
} catch (error) {
40+
console.error('Failed to initialize BridgeJS Playground:', error);
41+
this.showError('Failed to initialize application: ' + error.message);
42+
}
43+
}
44+
45+
// Initialize BridgeJS
46+
async initializeBridgeJS() {
47+
try {
48+
// Import the BridgeJS module
49+
const { init } = await import("../../.build/plugins/PackageToJS/outputs/Package/index.js");
50+
const { exports } = await init({
51+
imports: {
52+
createTS2Skeleton: this.createTS2Skeleton
53+
}
54+
});
55+
this.playBridgeJS = new exports.PlayBridgeJS();
56+
console.log('BridgeJS initialized successfully');
57+
} catch (error) {
58+
console.error('Failed to initialize BridgeJS:', error);
59+
throw new Error('BridgeJS initialization failed: ' + error.message);
60+
}
61+
}
62+
63+
// Set up event listeners
64+
setupEventListeners() {
65+
// Add change listeners for real-time generation
66+
this.editorSystem.addChangeListeners(() => {
67+
// Debounce generation to avoid excessive calls
68+
if (this.generateTimeout) {
69+
clearTimeout(this.generateTimeout);
70+
}
71+
this.generateTimeout = setTimeout(() => this.generateCode(), 300);
72+
});
73+
74+
// Handle window resize
75+
window.addEventListener('resize', () => {
76+
this.editorSystem.updateLayout();
77+
});
78+
}
79+
80+
createTS2Skeleton() {
81+
return {
82+
convert: (dtsCode) => {
83+
const virtualFilePath = "bridge-js.d.ts"
84+
const virtualHost = {
85+
fileExists: fileName => fileName === virtualFilePath,
86+
readFile: fileName => dtsCode,
87+
getSourceFile: (fileName, languageVersion) => {
88+
const sourceText = dtsCode;
89+
if (sourceText === undefined) return undefined;
90+
return ts.createSourceFile(fileName, sourceText, languageVersion);
91+
},
92+
getDefaultLibFileName: options => "lib.d.ts",
93+
writeFile: (fileName, data) => {
94+
console.log(`[emit] ${fileName}:\n${data}`);
95+
},
96+
getCurrentDirectory: () => "",
97+
getDirectories: () => [],
98+
getCanonicalFileName: fileName => fileName,
99+
getNewLine: () => "\n",
100+
useCaseSensitiveFileNames: () => true
101+
}
102+
// Create TypeScript program from d.ts content
103+
const tsProgram = ts.createProgram({
104+
rootNames: [virtualFilePath],
105+
host: virtualHost,
106+
options: {
107+
noEmit: true,
108+
declaration: true,
109+
}
110+
})
111+
112+
// Create diagnostic engine for error reporting
113+
const diagnosticEngine = {
114+
print: (level, message, node) => {
115+
console.log(`[${level}] ${message}`);
116+
if (level === 'error') {
117+
this.showError(`TypeScript Error: ${message}`);
118+
}
119+
}
120+
};
121+
122+
// Process the TypeScript definitions to generate skeleton
123+
const processor = new TypeProcessor(tsProgram.getTypeChecker(), diagnosticEngine);
124+
125+
const skeleton = processor.processTypeDeclarations(tsProgram, virtualFilePath);
126+
127+
return JSON.stringify(skeleton);
128+
}
129+
}
130+
}
131+
132+
// Generate code through BridgeJS
133+
async generateCode() {
134+
if (!this.playBridgeJS) {
135+
this.showError('BridgeJS is not initialized');
136+
return;
137+
}
138+
139+
try {
140+
this.hideError();
141+
142+
const inputs = this.editorSystem.getInputs();
143+
const swiftCode = inputs.swift;
144+
const dtsCode = inputs.dts;
145+
146+
// Process the code and get PlayBridgeJSOutput
147+
const result = this.playBridgeJS.update(swiftCode, dtsCode);
148+
149+
// Update outputs using the PlayBridgeJSOutput object
150+
this.editorSystem.updateOutputs(result);
151+
152+
console.log('Code generated successfully');
153+
154+
} catch (error) {
155+
console.error('Error generating code:', error);
156+
this.showError('Error generating code: ' + error.message);
157+
}
158+
}
159+
160+
// Show error message
161+
showError(message) {
162+
this.errorMessage.textContent = message;
163+
this.errorDisplay.classList.add('show');
164+
}
165+
166+
// Hide error message
167+
hideError() {
168+
this.errorDisplay.classList.remove('show');
169+
}
170+
}

0 commit comments

Comments
 (0)