From 9dc64814b4dccb1e12924404486a1e6fc9210fb8 Mon Sep 17 00:00:00 2001 From: Prad Nukala Date: Wed, 7 Jan 2026 18:33:59 -0500 Subject: [PATCH] refactor(MAKEFILE): migrate to Vite and remove sqlc dependency --- .gitignore | 4 + Makefile | 98 +++++++++------------ example/index.html | 197 ++++++++++++----------------------------- example/package.json | 2 +- example/test.js | 205 ------------------------------------------- 5 files changed, 103 insertions(+), 403 deletions(-) delete mode 100644 example/test.js diff --git a/.gitignore b/.gitignore index 5c5acf0..e070b11 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ example/node_modules build example/enclave.wasm +src/dist +src/node_modules +dist +node_modules diff --git a/Makefile b/Makefile index badaa45..6836929 100644 --- a/Makefile +++ b/Makefile @@ -1,84 +1,72 @@ -.PHONY: all generate build build-debug build-opt test test-cover test-plugin lint fmt vet clean tidy deps verify serve help +.PHONY: start deps build sdk dev test test-plugin lint fmt clean help -MODULE := enclave BINARY := enclave.wasm BUILD_DIR := example -all: generate build +# === Primary Commands === -generate: - @sqlc generate +start: deps build sdk dev + +deps: + @command -v sqlc >/dev/null || go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest + @command -v golangci-lint >/dev/null || go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + @bun install + @cd example && bun install build: + @echo "Building WASM plugin..." @GOOS=wasip1 GOARCH=wasm go build -o $(BUILD_DIR)/$(BINARY) . + @echo "Built $(BUILD_DIR)/$(BINARY)" -build-debug: - @GOOS=wasip1 GOARCH=wasm go build -gcflags="all=-N -l" -o $(BUILD_DIR)/$(BINARY) . +sdk: + @echo "Building TypeScript SDK..." + @bun run build + @echo "Built dist/enclave.js" -build-opt: - @GOOS=wasip1 GOARCH=wasm go build -ldflags="-s -w" -o $(BUILD_DIR)/$(BINARY) . - @wasm-opt -Os $(BUILD_DIR)/$(BINARY) -o $(BUILD_DIR)/$(BINARY) +dev: + @echo "Starting dev server at http://localhost:8080" + @cd example && bun run dev + +# === Testing === test: @go test -v ./... -test-cover: - @go test -coverprofile=coverage.out ./... - @go tool cover -html=coverage.out -o coverage.html +test-plugin: build + @echo "Testing generate()..." + @extism call $(BUILD_DIR)/$(BINARY) generate --input '{"credential":"dGVzdC1jcmVkZW50aWFs"}' --wasi + @echo "\nTesting query()..." + @extism call $(BUILD_DIR)/$(BINARY) query --input '{"did":""}' --wasi -test-plugin: - @extism call $(BUILD_DIR)/$(BINARY) generate --input '{"credential":"dGVzdA=="}' --wasi +test-sdk: sdk + @cd example && bun run test -serve: build - @echo "Starting Vite dev server at http://localhost:8080" - @cd example && npm run dev +# === Code Quality === lint: @golangci-lint run ./... fmt: @go fmt ./... - @gofumpt -w . + @bun run --filter '*' format 2>/dev/null || true -vet: - @go vet ./... +generate: + @sqlc generate + +# === Utilities === clean: @rm -f $(BUILD_DIR)/$(BINARY) - @rm -f coverage.out coverage.html - -tidy: - @go mod tidy - -deps: - @go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest - @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest - @go install mvdan.cc/gofumpt@latest - @cd example && npm install - @echo "Install Extism CLI: https://extism.org/docs/install" - -verify: fmt vet lint test + @rm -rf dist help: - @echo "Motr Enclave - Extism Plugin (Go 1.25/wasip1)" + @echo "Motr Enclave" @echo "" - @echo "Build targets:" - @echo " build - Build WASM plugin for wasip1" - @echo " build-debug - Build with debug symbols" - @echo " build-opt - Build optimized (requires wasm-opt)" - @echo "" - @echo "Development targets:" - @echo " generate - Run sqlc to generate Go code" - @echo " test - Run tests" - @echo " test-cover - Run tests with coverage" - @echo " test-plugin - Test plugin with Extism CLI" - @echo " serve - Build and serve example/ for browser testing" - @echo " lint - Run golangci-lint" - @echo " fmt - Format code" - @echo " vet - Run go vet" - @echo " verify - Run fmt, vet, lint, and test" - @echo "" - @echo "Utility targets:" - @echo " clean - Remove build artifacts" - @echo " tidy - Run go mod tidy" - @echo " deps - Install development dependencies" + @echo " make start - Full setup + dev server (recommended)" + @echo " make build - Build WASM plugin" + @echo " make sdk - Build TypeScript SDK" + @echo " make dev - Start dev server" + @echo " make test - Run Go tests" + @echo " make test-plugin - Test plugin with Extism CLI" + @echo " make test-sdk - Run SDK tests in browser" + @echo " make clean - Remove build artifacts" diff --git a/example/index.html b/example/index.html index 70b9eb3..446067a 100644 --- a/example/index.html +++ b/example/index.html @@ -1,168 +1,81 @@ - - - Motr Enclave Test - + + + Motr Enclave + -

Motr Enclave Plugin Test

+
+

Motr Enclave

-

Plugin Status

-
Loading plugin...
- +

Status

+ Loading... +
-

generate()

-

Initialize database with WebAuthn credential

- - - -
+

generate(credential)

+ +
-

load()

-

Load database from serialized buffer

- - - - -
+

load(database)

+ +
-

exec()

-

Execute action with GitHub-style filter syntax

- - - - -
- - - - - -
-
+

exec(filter)

+ +
+ + + + +
-

query()

-

Resolve DID to document with resources

- - - -
+

query(did)

+ +
-

Console Log

- -
+

Log

+ +
+
- + diff --git a/example/package.json b/example/package.json index c604c65..6a54102 100644 --- a/example/package.json +++ b/example/package.json @@ -5,7 +5,7 @@ "scripts": { "dev": "vite", "build": "vite build", - "preview": "vite preview" + "test": "vite --port 8081 & sleep 2 && node test.runner.js; kill %1" }, "dependencies": { "@extism/extism": "^2.0.0-rc13" diff --git a/example/test.js b/example/test.js deleted file mode 100644 index 9537320..0000000 --- a/example/test.js +++ /dev/null @@ -1,205 +0,0 @@ -import createPlugin from '@extism/extism'; - -let plugin = null; -let generatedDatabase = null; - -function log(message, type = 'info') { - const consoleLog = document.getElementById('consoleLog'); - const timestamp = new Date().toISOString().split('T')[1].split('.')[0]; - const prefix = type === 'error' ? '[ERROR]' : type === 'success' ? '[OK]' : '[INFO]'; - consoleLog.textContent += `${timestamp} ${prefix} ${message}\n`; - consoleLog.scrollTop = consoleLog.scrollHeight; - console[type === 'error' ? 'error' : 'log'](message); -} - -function setStatus(message, type) { - const status = document.getElementById('status'); - status.textContent = message; - status.className = `status ${type}`; -} - -function formatOutput(data) { - try { - if (typeof data === 'string') { - const parsed = JSON.parse(data); - return JSON.stringify(parsed, null, 2); - } - return JSON.stringify(data, null, 2); - } catch { - return String(data); - } -} - -async function loadPlugin() { - setStatus('Loading plugin...', 'loading'); - log('Loading enclave.wasm...'); - - try { - const wasmUrl = new URL('./enclave.wasm', window.location.href).href; - log(`WASM URL: ${wasmUrl}`); - - const manifest = { - wasm: [{ url: wasmUrl }] - }; - - plugin = await createPlugin(manifest, { - useWasi: true, - logger: console - }); - - setStatus('Plugin loaded successfully', 'success'); - log('Plugin loaded successfully', 'success'); - } catch (error) { - setStatus(`Failed to load plugin: ${error.message}`, 'error'); - log(`Failed to load plugin: ${error.message}`, 'error'); - } -} - -async function testGenerate() { - if (!plugin) { - log('Plugin not loaded', 'error'); - return; - } - - const output = document.getElementById('generateOutput'); - const credential = document.getElementById('credentialInput').value; - - log(`Calling generate() with credential: ${credential.substring(0, 20)}...`); - output.textContent = 'Running...'; - - try { - const input = JSON.stringify({ credential }); - const result = await plugin.call('generate', input); - const data = result.json(); - - output.textContent = formatOutput(data); - log(`generate() completed. DID: ${data.did}`, 'success'); - - if (data.database) { - generatedDatabase = data.database; - log('Database buffer stored for load() test'); - } - } catch (error) { - output.textContent = `Error: ${error.message}`; - log(`generate() failed: ${error.message}`, 'error'); - } -} - -async function testLoad() { - if (!plugin) { - log('Plugin not loaded', 'error'); - return; - } - - const output = document.getElementById('loadOutput'); - const databaseInput = document.getElementById('databaseInput').value; - - if (!databaseInput) { - output.textContent = 'Error: Database buffer is required'; - log('load() requires database buffer', 'error'); - return; - } - - log('Calling load()...'); - output.textContent = 'Running...'; - - try { - const input = JSON.stringify({ - database: Array.from(atob(databaseInput), c => c.charCodeAt(0)) - }); - const result = await plugin.call('load', input); - const data = result.json(); - - output.textContent = formatOutput(data); - log(`load() completed. Success: ${data.success}`, data.success ? 'success' : 'error'); - } catch (error) { - output.textContent = `Error: ${error.message}`; - log(`load() failed: ${error.message}`, 'error'); - } -} - -function useGeneratedDb() { - if (generatedDatabase) { - const base64 = btoa(String.fromCharCode(...generatedDatabase)); - document.getElementById('databaseInput').value = base64; - log('Populated database input with generated database'); - } else { - log('No generated database available. Run generate() first.', 'error'); - } -} - -async function testExec() { - if (!plugin) { - log('Plugin not loaded', 'error'); - return; - } - - const output = document.getElementById('execOutput'); - const filter = document.getElementById('filterInput').value; - const token = document.getElementById('tokenInput').value; - - if (!filter) { - output.textContent = 'Error: Filter is required'; - log('exec() requires filter', 'error'); - return; - } - - log(`Calling exec() with filter: ${filter}`); - output.textContent = 'Running...'; - - try { - const input = JSON.stringify({ filter, token: token || undefined }); - const result = await plugin.call('exec', input); - const data = result.json(); - - output.textContent = formatOutput(data); - log(`exec() completed. Success: ${data.success}`, data.success ? 'success' : 'error'); - } catch (error) { - output.textContent = `Error: ${error.message}`; - log(`exec() failed: ${error.message}`, 'error'); - } -} - -function setFilter(filter) { - document.getElementById('filterInput').value = filter; -} - -async function testQuery() { - if (!plugin) { - log('Plugin not loaded', 'error'); - return; - } - - const output = document.getElementById('queryOutput'); - const did = document.getElementById('didInput').value; - - log(`Calling query() with DID: ${did || '(current)'}`); - output.textContent = 'Running...'; - - try { - const input = JSON.stringify({ did: did || '' }); - const result = await plugin.call('query', input); - const data = result.json(); - - output.textContent = formatOutput(data); - log(`query() completed. DID: ${data.did}`, 'success'); - } catch (error) { - output.textContent = `Error: ${error.message}`; - log(`query() failed: ${error.message}`, 'error'); - } -} - -function clearLog() { - document.getElementById('consoleLog').textContent = ''; -} - -window.loadPlugin = loadPlugin; -window.testGenerate = testGenerate; -window.testLoad = testLoad; -window.useGeneratedDb = useGeneratedDb; -window.testExec = testExec; -window.setFilter = setFilter; -window.testQuery = testQuery; -window.clearLog = clearLog; - -loadPlugin();