Skip to content

Commit eb94baf

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

19 files changed

+1254
-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: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
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+
75+
createTS2Skeleton() {
76+
return {
77+
convert: (dtsCode) => {
78+
const virtualFilePath = "bridge-js.d.ts"
79+
const virtualHost = {
80+
fileExists: fileName => fileName === virtualFilePath,
81+
readFile: fileName => dtsCode,
82+
getSourceFile: (fileName, languageVersion) => {
83+
const sourceText = dtsCode;
84+
if (sourceText === undefined) return undefined;
85+
return ts.createSourceFile(fileName, sourceText, languageVersion);
86+
},
87+
getDefaultLibFileName: options => "lib.d.ts",
88+
writeFile: (fileName, data) => {
89+
console.log(`[emit] ${fileName}:\n${data}`);
90+
},
91+
getCurrentDirectory: () => "",
92+
getDirectories: () => [],
93+
getCanonicalFileName: fileName => fileName,
94+
getNewLine: () => "\n",
95+
useCaseSensitiveFileNames: () => true
96+
}
97+
// Create TypeScript program from d.ts content
98+
const tsProgram = ts.createProgram({
99+
rootNames: [virtualFilePath],
100+
host: virtualHost,
101+
options: {
102+
noEmit: true,
103+
declaration: true,
104+
}
105+
})
106+
107+
// Create diagnostic engine for error reporting
108+
const diagnosticEngine = {
109+
print: (level, message, node) => {
110+
console.log(`[${level}] ${message}`);
111+
if (level === 'error') {
112+
this.showError(`TypeScript Error: ${message}`);
113+
}
114+
}
115+
};
116+
117+
// Process the TypeScript definitions to generate skeleton
118+
const processor = new TypeProcessor(tsProgram.getTypeChecker(), diagnosticEngine);
119+
120+
const skeleton = processor.processTypeDeclarations(tsProgram, virtualFilePath);
121+
122+
return JSON.stringify(skeleton);
123+
}
124+
}
125+
}
126+
127+
// Generate code through BridgeJS
128+
async generateCode() {
129+
if (!this.playBridgeJS) {
130+
this.showError('BridgeJS is not initialized');
131+
return;
132+
}
133+
134+
try {
135+
this.hideError();
136+
137+
const inputs = this.editorSystem.getInputs();
138+
const swiftCode = inputs.swift;
139+
const dtsCode = inputs.dts;
140+
141+
// Process the code and get PlayBridgeJSOutput
142+
const result = this.playBridgeJS.update(swiftCode, dtsCode);
143+
144+
// Update outputs using the PlayBridgeJSOutput object
145+
this.editorSystem.updateOutputs(result);
146+
147+
console.log('Code generated successfully');
148+
149+
} catch (error) {
150+
console.error('Error generating code:', error);
151+
this.showError('Error generating code: ' + error.message);
152+
}
153+
}
154+
155+
// Show error message
156+
showError(message) {
157+
this.errorMessage.textContent = message;
158+
this.errorDisplay.classList.add('show');
159+
}
160+
161+
// Hide error message
162+
hideError() {
163+
this.errorDisplay.classList.remove('show');
164+
}
165+
}

0 commit comments

Comments
 (0)