@blocksuite/store
Advanced tools
Comparing version 0.3.0-alpha.11 to 0.3.0-alpha.12
{ | ||
"name": "@blocksuite/store", | ||
"version": "0.3.0-alpha.11", | ||
"version": "0.3.0-alpha.12", | ||
"description": "BlockSuite data store built for general purpose state management.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
// checkout https://vitest.dev/guide/debugging.html for debugging tests | ||
import { assert, describe, expect, it } from 'vitest'; | ||
import { | ||
BaseBlockModel, | ||
Signal, | ||
Workspace, | ||
Page, | ||
createAutoIncrementIdGenerator, | ||
} from '..'; | ||
import { BaseBlockModel, Signal, Workspace, Page, Generator } from '..'; | ||
@@ -22,3 +16,3 @@ // Use manual per-module import/export to support vitest environment on Node.js | ||
function createTestOptions() { | ||
const idGenerator = createAutoIncrementIdGenerator(); | ||
const idGenerator = Generator.AutoIncrement; | ||
return { idGenerator }; | ||
@@ -109,41 +103,2 @@ } | ||
it('can set custom idGenerator', async () => { | ||
const options = { | ||
...createTestOptions(), | ||
idGenerator: (() => { | ||
const keys = ['7', '100', '2']; | ||
let i = 0; | ||
return () => keys[i++]; | ||
})(), | ||
}; | ||
const workspace = new Workspace(options).register(BlockSchema); | ||
const page = await createPage(workspace); | ||
page.addBlock({ flavour: 'affine:page' }); | ||
page.addBlock({ flavour: 'affine:paragraph' }); | ||
page.addBlock({ flavour: 'affine:paragraph' }); | ||
assert.deepEqual(serialize(page)[spaceId], { | ||
'7': { | ||
'sys:children': ['100', '2'], | ||
'sys:flavour': 'affine:page', | ||
'sys:id': '7', | ||
}, | ||
'100': { | ||
'sys:children': [], | ||
'sys:flavour': 'affine:paragraph', | ||
'sys:id': '100', | ||
'prop:text': '', | ||
'prop:type': 'text', | ||
}, | ||
'2': { | ||
'sys:children': [], | ||
'sys:flavour': 'affine:paragraph', | ||
'sys:id': '2', | ||
'prop:text': '', | ||
'prop:type': 'text', | ||
}, | ||
}); | ||
}); | ||
it('can add model with props', async () => { | ||
@@ -150,0 +105,0 @@ const page = await createTestPage(); |
@@ -5,2 +5,8 @@ import type { Page } from './workspace'; | ||
// ported from lit | ||
interface StaticValue { | ||
_$litStatic$: string; | ||
r: unknown; | ||
} | ||
export interface IBaseBlockProps { | ||
@@ -18,2 +24,5 @@ flavour: string; | ||
static version: [number, number]; | ||
flavour!: string; | ||
tag!: StaticValue; | ||
id: string; | ||
@@ -25,5 +34,3 @@ page: Page; | ||
flavour!: string; | ||
type!: string; | ||
id: string; | ||
children: BaseBlockModel[]; | ||
@@ -30,0 +37,0 @@ // TODO use schema |
@@ -30,2 +30,17 @@ import type * as Y from 'yjs'; | ||
// When using playground from blocksuite repo, this comes from "serve" script in "@blocksuite/store" package. | ||
// We use our own sync server because a local service for sync makes everything much faster for dev. | ||
const LOCAL_SIGNALING = ['ws://localhost:4444']; | ||
const DEFAULT_SIGNALING = [ | ||
// Default config from yjs (but these are kinda slow by comparison to self host sync ~100ms-+1000ms latency observed). | ||
// This slowness is also avoided in order to improve test reliability in CI. | ||
'wss://y-webrtc-signaling-us.herokuapp.com', | ||
'wss://y-webrtc-signaling-eu.herokuapp.com', | ||
]; | ||
const isWeb = typeof window !== 'undefined'; | ||
const isLocalhost = isWeb && window.location.hostname === 'localhost'; | ||
const signaling = isLocalhost ? LOCAL_SIGNALING : DEFAULT_SIGNALING; | ||
export class DebugDocProvider extends WebrtcProvider implements DocProvider { | ||
@@ -35,11 +50,3 @@ constructor(room: string, doc: Y.Doc, options?: { awareness?: Awareness }) { | ||
awareness: options?.awareness ?? null, | ||
signaling: [ | ||
// When using playground from blocksuite repo, this comes from "serve" script in "@blocksuite/store" package. | ||
// We use our own sync server because a local service for sync makes everything much faster for dev. | ||
'ws://localhost:4444', | ||
// // Default config from yjs (but these are kinda slow by comparison to self host sync ~100ms-+1000ms latency observed). | ||
// // This slowness is also avoided in order to improve test reliability in CI. | ||
// 'wss://y-webrtc-signaling-us.herokuapp.com', | ||
// 'wss://y-webrtc-signaling-eu.herokuapp.com', | ||
], | ||
signaling, | ||
// YJS has broken default types. 🥲 | ||
@@ -46,0 +53,0 @@ ...({} as { |
@@ -7,3 +7,7 @@ import type { Space } from './space'; | ||
import { serializeYDoc, yDocToJSXNode } from './utils/jsx'; | ||
import { uuidv4 } from './utils/id-generator'; | ||
import { | ||
createAutoIncrementIdGenerator, | ||
createAutoIncrementIdGeneratorByClientId, | ||
uuidv4, | ||
} from './utils/id-generator'; | ||
@@ -16,2 +20,21 @@ export interface SerializedStore { | ||
export enum Generator { | ||
/** | ||
* Default mode, generator for the unpredictable id | ||
*/ | ||
UUIDv4 = 'uuidV4', | ||
/** | ||
* This generator is trying to fix the real-time collaboration on debug mode. | ||
* This will make generator predictable and won't make conflict | ||
* @link https://docs.yjs.dev/api/faq#i-get-a-new-clientid-for-every-session-is-there-a-way-to-make-it-static-for-a-peer-accessing-the-doc | ||
*/ | ||
AutoIncrementByClientId = 'autoIncrementByClientId', | ||
/** | ||
* **Warning**: This generator mode will crash the collaborative feature | ||
* if multiple clients are adding new blocks. | ||
* Use this mode only if you know what you're doing. | ||
*/ | ||
AutoIncrement = 'autoIncrement', | ||
} | ||
export interface StoreOptions { | ||
@@ -21,3 +44,3 @@ room?: string; | ||
awareness?: Awareness; | ||
idGenerator?: IdGenerator; | ||
idGenerator?: Generator; | ||
} | ||
@@ -42,3 +65,19 @@ | ||
this.awareness = awareness ?? new Awareness(this.doc); | ||
this.idGenerator = idGenerator ?? uuidv4; | ||
switch (idGenerator) { | ||
case Generator.AutoIncrement: { | ||
this.idGenerator = createAutoIncrementIdGenerator(); | ||
break; | ||
} | ||
case Generator.AutoIncrementByClientId: { | ||
this.idGenerator = createAutoIncrementIdGeneratorByClientId( | ||
this.doc.clientID | ||
); | ||
break; | ||
} | ||
case Generator.UUIDv4: | ||
default: { | ||
this.idGenerator = uuidv4; | ||
break; | ||
} | ||
} | ||
this.providers = providers.map( | ||
@@ -45,0 +84,0 @@ ProviderConstructor => |
@@ -10,4 +10,11 @@ import { uuidv4 as uuidv4IdGenerator } from 'lib0/random'; | ||
export function createAutoIncrementIdGeneratorByClientId( | ||
clientId: number | ||
): IdGenerator { | ||
let i = 0; | ||
return () => `${clientId}:${i++}`; | ||
} | ||
export function uuidv4() { | ||
return uuidv4IdGenerator(); | ||
} |
@@ -10,2 +10,4 @@ import * as Y from 'yjs'; | ||
import { PrelimText, Text, TextType } from '../text-adapter'; | ||
import type { Workspace } from '../workspace'; | ||
import { fromBase64, toBase64 } from 'lib0/buffer'; | ||
@@ -196,1 +198,9 @@ const SYS_KEYS = new Set(['id', 'flavour', 'children']); | ||
} | ||
export function encodeWorkspaceAsYjsUpdateV2(workspace: Workspace): string { | ||
return toBase64(Y.encodeStateAsUpdateV2(workspace.doc)); | ||
} | ||
export function applyYjsUpdateV2(workspace: Workspace, update: string): void { | ||
Y.applyUpdateV2(workspace.doc, fromBase64(update)); | ||
} |
@@ -37,3 +37,3 @@ import * as Y from 'yjs'; | ||
const IS_WEB = typeof window !== 'undefined'; | ||
const isWeb = typeof window !== 'undefined'; | ||
@@ -364,3 +364,3 @@ function createChildMap(yChildIds: Y.Array<string>) { | ||
private _historyAddObserver = (event: { stackItem: StackItem }) => { | ||
if (IS_WEB) { | ||
if (isWeb) { | ||
event.stackItem.meta.set( | ||
@@ -413,3 +413,3 @@ 'cursor-location', | ||
'affine:list', | ||
'affine:code-block', | ||
'affine:code', | ||
]) && | ||
@@ -416,0 +416,0 @@ !yBlock.get('prop:text') |
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"rootDir": "./src/", | ||
"baseUrl": ".", | ||
"outDir": "./dist/", | ||
@@ -6,0 +6,0 @@ "noEmit": false |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
441776
178
7046
2