Skip to content

Commit

Permalink
feat: y-websocket
Browse files Browse the repository at this point in the history
  • Loading branch information
nusr committed Jan 4, 2025
1 parent f16c9cb commit b23be4c
Show file tree
Hide file tree
Showing 28 changed files with 200 additions and 713 deletions.
6 changes: 1 addition & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
# supabase url
VITE_SUPABASE_URL=
# supabase anon key
VITE_SUPABASE_ANON_KEY=
# default excel id
VITE_DEFAULT_EXCEL_ID=
VITE_DEFAULT_EXCEL_ID=
2 changes: 0 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ concurrency:
cancel-in-progress: true

env:
VITE_SUPABASE_URL: ${{ vars.VITE_SUPABASE_URL }}
VITE_SUPABASE_ANON_KEY: ${{ vars.VITE_SUPABASE_ANON_KEY }}
VITE_DEFAULT_EXCEL_ID: ${{ vars.VITE_DEFAULT_EXCEL_ID }}

jobs:
Expand Down
3 changes: 0 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ jobs:
run: |
npm i -g pnpm
pnpm i
pnpm exec playwright install --with-deps
npm run type-check
npm run lint
npm run build
Expand All @@ -29,5 +28,3 @@ jobs:
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
- name: E2E test
run: npm run e2e
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ vite.config.mts.*.mjs
diff.txt
.nx
pnpm-lock.yaml
levelDB
30 changes: 2 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
![GitHub](https://img.shields.io/github/license/nusr/excel.svg)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/nusr/excel.svg)

[online demo](https://stackblitz.com/edit/nusr-excel-collaboration)
[online demo](https://nusr.github.io/excel)

![demo](./scripts/demo.gif)

Expand All @@ -31,33 +31,7 @@ cd excel

npm i -g pnpm
pnpm i
npm run start
```

## Environment

Create an `.env` file and modify it as the `.env.example` file

## Supbase

Collaborative editing uses [Supabase](https://supabase.com/) as backend.
You need to configure `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY`.
With Row Level Security (RLS) disabled, anonymous users will be able to read/write data in the table.

```sql
CREATE TABLE IF NOT EXISTS history (
id SERIAL PRIMARY KEY,
doc_id UUID,
update TEXT,
create_time TIMESTAMP WITH TIME ZONE NULL DEFAULT NOW(),
);

-- document table need to enable real time
CREATE TABLE IF NOT EXISTS document (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
name VARCHAR(20),
create_time TIMESTAMP WITH TIME ZONE NULL DEFAULT NOW(),
);
npm run dev
```

## Supported Features
Expand Down
76 changes: 28 additions & 48 deletions demo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,78 +8,58 @@ import {
type WorkerMethod,
Excel,
version,
UserItem,
useUserInfo,
} from '../src';
import Worker from './worker?worker';
import './sentry';
import { CollaborationProvider } from './server';
import { WebsocketProvider } from 'y-websocket';
import { WebrtcProvider } from 'y-webrtc';

const workerInstance = wrap<WorkerMethod>(new Worker());

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

const providerType = new URLSearchParams(location.search).get('providerType');

let provider: CollaborationProvider | undefined = undefined;
if (providerType === 'websocket') {
const websocketProvider = new WebsocketProvider(
'ws://localhost:1234',
doc.guid,
doc,
);

websocketProvider.on('status', (...args) => {
console.log('status:', ...args);
});
websocketProvider.on('sync', (...args) => {
console.log('sync:', ...args);
});
console.log('websocketProvider', websocketProvider);
} else if (providerType === 'webrtc') {
const webrtcProvider = new WebrtcProvider(doc.guid, doc, {
signaling: ['ws://localhost:4444'],
});

webrtcProvider.on('synced', (...args) => {
console.log('synced:', ...args);
});
webrtcProvider.on('peers', (...args) => {
console.log('peers:', ...args);
});
webrtcProvider.on('status', (...args) => {
console.log('status:', ...args);
});
console.log('webrtcProvider', webrtcProvider);
} else {
provider = new CollaborationProvider({
doc,
supabaseUrl: import.meta.env.VITE_SUPABASE_URL,
supabaseAnonKey: import.meta.env.VITE_SUPABASE_ANON_KEY,
enableIndexDb: false,
});
const provider = new WebsocketProvider('ws://localhost:1234', doc.guid, doc, {
connect: false,
});

provider.setAwarenessChangeCallback((users) => {
useUserInfo.getState().setUsers(users);
});
}
provider.connect();
provider.awareness.on('update', () => {
const list: UserItem[] = [];
for (const item of provider.awareness.getStates().entries()) {
const [key, value] = item;
if (!value.range || key === doc.clientID) {
continue;
}
list.push({ clientId: key, range: value.range });
}
console.log(list)
useUserInfo.getState().setUsers(list);
});

const workerInstance = wrap<WorkerMethod>(new Worker());
const controller = initController({
worker: workerInstance,
doc,
});

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

doc.on('update', () => {
controller.emit('renderChange', { changeSet: new Set(['rangeMap']) });
});

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

createRoot(document.getElementById('root')!).render(
<StrictMode>
<StateContext value={{ provider, controller }}>
<StateContext value={{ controller }}>
<Excel />
</StateContext>
</StrictMode>,
Expand Down
86 changes: 0 additions & 86 deletions demo/local.ts

This file was deleted.

Loading

0 comments on commit b23be4c

Please sign in to comment.