Skip to content

Commit

Permalink
feat: local server
Browse files Browse the repository at this point in the history
  • Loading branch information
nusr committed Jan 6, 2025
1 parent eab76e5 commit 19cc16d
Show file tree
Hide file tree
Showing 27 changed files with 500 additions and 121 deletions.
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CALLBACK_URL=http://localhost:4000/sync
CALLBACK_OBJECTS='{"excel":"Map"}'
2 changes: 0 additions & 2 deletions .env.example

This file was deleted.

13 changes: 5 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
node_modules
node_modules/**
*/node_modules
dist
.vscode
.idea
Expand All @@ -24,14 +25,10 @@ package-lock.json
/blob-report/
/playwright/.cache/
build
.env
.env.server


.nx/cache
.nx/workspace-data
vite.config.mts.*.mjs
diff.txt
.nx
pnpm-lock.yaml
levelDB
levelDB
uploads
dev.db
dev.db-journal
3 changes: 1 addition & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ npm run lint
npm run type-check
npm run test
npm run build
npm run build:gh-pages
npm run update-md
npm run build:gh-pages
5 changes: 0 additions & 5 deletions TODO.md

This file was deleted.

33 changes: 23 additions & 10 deletions demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,35 @@ import {
version,
UserItem,
useUserInfo,
modelToChangeSet,
} from '../src';
import Worker from './worker?worker';
import './sentry';
import { WebsocketProvider } from 'y-websocket';
import { Provider } from './provider';

const docId =
import.meta.env.VITE_DEFAULT_EXCEL_ID ||
'184858c4-be37-41b5-af82-52689004e605';
const doc = initDoc({ guid: docId });
location.hash = `#${docId}`;

const provider = new WebsocketProvider('ws://localhost:1234', doc.guid, doc, {
connect: false,
});
// Github Pages no server
const isCI = Boolean(process.env.CI);

provider.connect();
provider.awareness.on('update', () => {
const webSocket = new WebsocketProvider(
isCI ? '' : 'ws://localhost:1234',
doc.guid,
doc,
{
connect: false,
},
);

webSocket.connect();
webSocket.awareness.on('update', () => {
const list: UserItem[] = [];
for (const item of provider.awareness.getStates().entries()) {
for (const item of webSocket.awareness.getStates().entries()) {
const [key, value] = item;
if (!value.range || key === doc.clientID) {
continue;
Expand All @@ -45,20 +55,23 @@ const controller = initController({
});

controller.on('rangeChange', (range) => {
provider.awareness.setLocalStateField('range', range);
webSocket.awareness.setLocalStateField('range', range);
});

doc.on('update', () => {
controller.emit('renderChange', { changeSet: new Set(['rangeMap']) });
doc.on('update', (_a, _b, _c, tran) => {
const changeSet = modelToChangeSet(tran);
controller.emit('renderChange', { changeSet });
});

(window as any).controller = controller;
(window as any).doc = doc;
(window as any).version = version;

const provider = isCI ? undefined : new Provider();

createRoot(document.getElementById('root')!).render(
<StrictMode>
<StateContext value={{ controller }}>
<StateContext value={{ controller, provider }}>
<Excel />
</StateContext>
</StrictMode>,
Expand Down
68 changes: 68 additions & 0 deletions demo/provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ICollaborationProvider, DocumentItem } from '../src';

const BASE_URL = 'http://localhost:4000';

async function fetchData<T>(
url: string,
method: 'POST' | 'GET' | 'PUT' | 'DELETE' = 'GET',
data: string | FormData = '',
) {
try {
const result = await fetch(`${BASE_URL}${url}`, {
method,
body: method === 'POST' || method === 'PUT' ? data : undefined,
headers:
typeof data === 'string'
? {
'Content-Type': 'application/json',
}
: undefined,
});
if (result.status !== 200) {
return;
}
const res = result.json();
return res as T;
} catch (error) {
console.log(error);
return;
}
}

export class Provider implements ICollaborationProvider {
async uploadFile(
docId: string,
file: File,
_base64: string,
): Promise<string> {
const form = new FormData();
form.append('file', file);
form.append('docId', docId);
const res = await fetchData<{ filePath: string }>('/upload', 'POST', form);
return res?.filePath ?? _base64;
}
downloadFile(_docId: string, filePath: string): Promise<string> {
return Promise.resolve(BASE_URL + filePath);
}
async addDocument(id: string) {
await fetchData<DocumentItem>(
'/document',
'POST',
JSON.stringify({ name: '', id }),
);
}
async updateDocument(
id: string,
data: Pick<DocumentItem, 'name' | 'content'>,
): Promise<void> {
await fetchData<DocumentItem>(
'/document/' + id,
'PUT',
JSON.stringify(data),
);
}
async getDocument(id: string): Promise<DocumentItem | undefined> {
const res = await fetchData<DocumentItem>('/document/' + id);
return res;
}
}
3 changes: 1 addition & 2 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ module.exports = {
options: {
metaObjectReplacement: {
VITE_IS_E2E: 'true',
VITE_SUPABASE_URL: '',
VITE_SUPABASE_ANON_KEY: '',
VITE_DEFAULT_EXCEL_ID: '',
},
},
},
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
},
"scripts": {
"start": "vite --force --host --port 3000",
"dev": "run-p start server",
"server": "cross-env YPERSISTENCE=./levelDB npx y-websocket",
"dev": "run-p start server websocket",
"websocket": "env-cmd -- npx y-websocket",
"server": "cd server && npm run dev",
"preview": "vite preview",
"type-check": "tsc",
"e2e": "playwright test",
Expand Down Expand Up @@ -58,6 +59,7 @@
"@vitejs/plugin-react": "4.3.4",
"canvas": "2.11.2",
"cross-env": "7.0.3",
"env-cmd": "^10.1.0",
"husky": "9.1.7",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default defineConfig({

/* Run your local dev server before starting the tests */
webServer: {
command: 'npm run start',
command: 'npm run dev',
url: 'http://127.0.0.1:3000',
reuseExistingServer: true,
},
Expand Down
11 changes: 11 additions & 0 deletions server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Start

```bash
npm i -g pnpm
pnpm i
npm run dev
```

## Database

[SQL](./prisma/migrations/20250106130540_init/migration.sql)
27 changes: 27 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "server",
"main": "index.ts",
"scripts": {
"dev": "npx tsx ./src/index.ts",
"build": "npx tsc",
"postinstall": "npx prisma migrate dev --name init"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/koa": "^2.15.0",
"@types/koa__cors": "^5.0.0",
"@types/koa__router": "^12.0.4",
"@types/node": "^22.10.5",
"prisma": "^6.1.0",
"ts-node": "^10.9.2",
"tsx": "^4.19.2",
"typescript": "^5.7.2"
},
"dependencies": {
"@koa/cors": "^5.0.0",
"@koa/router": "^13.1.0",
"@prisma/client": "^6.1.0",
"koa": "^2.15.3",
"koa-body": "^6.0.1"
}
}
7 changes: 7 additions & 0 deletions server/prisma/migrations/20250106130540_init/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- CreateTable
CREATE TABLE "document" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT,
"create_time" TEXT NOT NULL,
"content" TEXT
);
3 changes: 3 additions & 0 deletions server/prisma/migrations/migration_lock.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "sqlite"
15 changes: 15 additions & 0 deletions server/prisma/schema.prisma
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "sqlite"
url = "file:./dev.db"
}

model document {
id String @id
name String?
create_time String
content String?
}
6 changes: 6 additions & 0 deletions server/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import app from "./route";

const port = 4000;
app.listen(port, () => {
console.log(`server running on http://localhost:${port}`);
});
Loading

0 comments on commit 19cc16d

Please sign in to comment.