Merge pull request #28089 from soney/master

Add ShareDB Typings
This commit is contained in:
Benjamin Lichtman
2018-08-30 11:41:54 -07:00
committed by GitHub
6 changed files with 245 additions and 0 deletions

63
types/sharedb/index.d.ts vendored Normal file
View File

@@ -0,0 +1,63 @@
// Type definitions for sharedb 1.0
// Project: https://github.com/share/sharedb
// Definitions by: Steve Oney <https://github.com/soney>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
/// <reference path="lib/sharedb.d.ts" />
import { Doc, Query, Error, Action, RawOp, Op } from './lib/sharedb';
type UseCallback = ((request: {action: Action, agent: any, req: any, collection: string, id: string, query: any, op: RawOp}, callback: () => void) => void);
interface PubSubOptions {
prefix?: string;
}
interface Stream {
id: string;
}
export = sharedb;
declare class sharedb {
constructor(options?: {db?: any, pubsub?: sharedb.PubSub, disableDocAction?: boolean, disableSpaceDelimitedActions?: boolean});
connect: () => sharedb.Connection;
addProjection(name: string, collection: string, fields: {}): any;
listen(stream: any): void;
close(callback?: (err: Error) => any): void;
use(action: Action, fn: UseCallback);
types: {
register: () => void
};
}
declare namespace sharedb {
abstract class PubSub {
private static shallowCopy(obj: any);
protected prefix?: string;
protected nextStreamId: number;
protected streamsCount: number;
protected streams: {
[channel: string]: Stream;
};
protected subscribed: {
[channel: string]: boolean;
};
protected constructor(options?: PubSubOptions);
close(callback?: (err: Error|null) => void): void;
publish(channels: string[], data: {[k: string]: any}, callback: (err: Error | null) => void): void;
subscribe(channel: string, callback: (err: Error | null, stream?: Stream) => void): void;
protected abstract _subscribe(channel: string, callback: (err: Error | null) => void): void;
protected abstract _unsubscribe(channel: string, callback: (err: Error | null) => void): void;
protected abstract _publish(channels: string[], data: any, callback: (err: Error | null) => void): void;
protected _emit(channel: string, data: {[k: string]: any}): void;
private _createStream(channel);
private _removeStream(channel, stream);
}
class Connection {
constructor(ws: WebSocket);
get(collectionName: string, documentID: string): Doc;
createFetchQuery(collectionName: string, query: string, options: {results?: Query[]}, callback: (err: Error, results: any) => any): Query;
createSubscribeQuery(collectionName: string, query: string, options: {results?: Query[]}, callback: (err: Error, results: any) => any): Query;
}
}

12
types/sharedb/lib/client.d.ts vendored Normal file
View File

@@ -0,0 +1,12 @@
/// <reference path="sharedb.d.ts" />
import * as WebSocket from 'ws';
import * as ShareDB from './sharedb';
export class Connection {
constructor(ws: WebSocket);
get(collectionName: string, documentID: string): Doc;
createFetchQuery(collectionName: string, query: string, options: {results?: Query[]}, callback: (err: Error, results: any) => any): Query;
createSubscribeQuery(collectionName: string, query: string, options: {results?: Query[]}, callback: (err: Error, results: any) => any): Query;
}
export type Doc = ShareDB.Doc;
export type Query = ShareDB.Query;

67
types/sharedb/lib/sharedb.d.ts vendored Normal file
View File

@@ -0,0 +1,67 @@
export type Path = ReadonlyArray<string|number>;
export type Snapshot = number;
export interface AddNumOp { p: Path; na: number; }
export interface ListInsertOp { p: Path; li: any; }
export interface ListDeleteOp { p: Path; ld: any; }
export interface ListReplaceOp { p: Path; li: any; ld: any; }
export interface ListMoveOp { p: Path; lm: any; }
export interface ObjectInsertOp { p: Path; oi: any; }
export interface ObjectDeleteOp { p: Path; od: any; }
export interface ObjectReplaceOp { p: Path; oi: any; od: any; }
export interface StringInsertOp { p: Path; si: string; }
export interface StringDeleteOp { p: Path; sd: string; }
export interface SubtypeOp { p: Path; t: string; o: any; }
export type Op = AddNumOp | ListInsertOp | ListDeleteOp | ListReplaceOp | ListMoveOp | ObjectInsertOp | ObjectDeleteOp | ObjectReplaceOp | StringInsertOp | StringDeleteOp | SubtypeOp;
export interface RawOp {
src: string;
seq: number;
v: number;
op: Op[];
m: any;
c: string;
d: string;
}
export type OTType = 'ot-text' | 'ot-json0' | 'ot-text-tp2' | 'rich-text';
export type Action = 'connect'|'op'|'doc'|'query'|'submit'|'apply'|'commit'|'after submit'|'receive';
export interface Error {
code: number;
message: string;
}
export interface ShareDBSourceOptions { source?: boolean; }
// interface ShareDBCreateOptions extends ShareDBSourceOptions {}
// interface ShareDBDelOptions extends ShareDBSourceOptions {}
// interface ShareDBSubmitOpOptions extends ShareDBSourceOptions {}
export type Callback = (err: Error) => any;
export class Doc {
type: string;
id: string;
data: any;
fetch: (callback: (err: Error) => void) => void;
subscribe: (callback: (err: Error) => void) => void;
on: (event: 'load'|'create'|'before op'|'op'|'del'|'error', callback: (...args: any[]) => any) => void;
ingestSnapshot: (snapshot: Snapshot, callback: Callback) => void;
destroy: () => void;
create(data: any, callback?: Callback): void;
create(data: any, type?: OTType, callback?: Callback): void;
create(data: any, type?: OTType, options?: ShareDBSourceOptions, callback?: Callback): void;
submitOp: (data: ReadonlyArray<Op>, options?: ShareDBSourceOptions, callback?: Callback) => void;
del: (options: ShareDBSourceOptions, callback: (err: Error) => void) => void;
removeListener: (eventName: string, listener: () => any) => void;
}
export class Query {
ready: boolean;
results: Doc[];
extra: any;
on: (event: 'ready'|'error'|'changed'|'insert'|'move'|'remove'|'extra', callback: (...args: any[]) => any) => any;
destroy: () => void;
}

View File

@@ -0,0 +1,71 @@
/// <reference types="qunit/v1" />
import * as ShareDB from 'sharedb';
import * as http from 'http';
import * as WebSocket from 'ws';
import { Duplex } from 'stream';
import * as ShareDBClient from 'sharedb/lib/client';
// Adapted from https://github.com/avital/websocket-json-stream
class WebSocketJSONStream extends Duplex {
constructor(private readonly ws: WebSocket) {
super({ objectMode: true });
this.ws.on('message', (msg: string) => {
this.push(JSON.parse(msg));
});
this.ws.on('close', () => {
this.push(null); // end readable stream
this.end(); // end writable stream
this.emit('close');
this.emit('end');
});
this.on('error', () => { ws.close(); });
this.on('end', () => { ws.close(); });
}
_read(): void {}
_write(msg: any, encoding: string, next: () => void): void {
this.ws.send(JSON.stringify(msg));
next();
}
}
const backend = new ShareDB();
const connection = backend.connect();
const doc = connection.get('examples', 'counter');
doc.fetch((err) => {
if (err) { throw err; }
if (doc.type === null) {
doc.create({ numClicks: 0 }, startServer);
} else {
startServer();
}
});
function startServer() {
const server = http.createServer();
// Connect any incoming WebSocket connection to ShareDB
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws, req) => {
const stream = new WebSocketJSONStream(ws);
backend.listen(stream);
});
server.listen(8080);
// console.log('Listening on http://localhost:8080');
startClient(() => {
server.close();
wss.close();
});
}
function startClient(callback) {
const socket = new WebSocket('ws://localhost:8080');
const connection = new ShareDBClient.Connection(socket);
const doc = connection.get('examples', 'counter');
doc.subscribe(() => {
doc.submitOp([{p: ['numClicks'], na: 1}]);
callback();
});
}

View File

@@ -0,0 +1,28 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": [
"es6",
"dom"
],
"noImplicitAny": false,
"noImplicitThis": false,
"strictNullChecks": false,
"strictFunctionTypes": true,
"baseUrl": "../",
"typeRoots": [
"../"
],
"paths": {
},
"types": [],
"noEmit": true,
"forceConsistentCasingInFileNames": true
},
"files": [
"lib/sharedb.d.ts",
"index.d.ts",
"lib/client.d.ts",
"sharedb-tests.ts"
]
}

View File

@@ -0,0 +1,4 @@
{
"extends": "dtslint/dt.json",
"rules": { }
}