UNPKG

@eweser/db

Version:
219 lines (201 loc) 6.6 kB
import type { Flashcard, Note, Profile, DocumentBase } from '@eweser/shared'; import type { Collections, Documents, YDoc } from '../types.js'; import { buildRef } from '../utils/index.js'; import { Room } from '../room.js'; import { Database } from '../index.js'; const db = new Database(); /** * some metadata that exists on each document */ const metadata: DocumentBase = { /** * The reference to the room and document. This is used to make relational links between documents. * format: <collection_key>.<room_id>.<document_id> * room_id includes the auth server url */ _ref: 'profiles.https://www.eweser.com|123abc.123abc', _id: '123abc', _created: 1653135317729, _updated: 1653135317729, _deleted: false, }; const profileYDoc: { documents: Documents<Profile> } = { documents: { ['default']: { firstName: 'Eweser', ...metadata, }, }, }; const profilePrivateYDoc: { documents: Documents<Profile> } = { documents: { ['default']: { lastName: 'DB', ...metadata, }, }, }; const myStudyNotesYDoc: { documents: Documents<Note> } = { documents: { ['0']: { text: 'A fact about Typescript', ...metadata, _ref: 'notes.https://www.eweser.com|0.0', _id: '0', }, ['1']: { text: 'Second fact about Typescript', ...metadata, _id: '0', _ref: 'notes.https://www.eweser.com|0.1', }, ['abc']: { text: 'Third fact about Typescript. Uses a string for id', ...metadata, _id: 'abc', _ref: 'notes.https://www.eweser.com|0.abc', }, }, }; const typescriptFlashcardsYDoc: { documents: Documents<Flashcard> } = { documents: { ['0']: { frontText: 'Question', backText: 'Answer', // links to other document ref noteRefs: ['notes.my_study_notes.0'], // or use buildRef() ...metadata, }, }, }; const chineseFlashcardsYDoc: { documents: Documents<Flashcard> } = { documents: { ['0']: { frontText: 'What does 火 mean?', backText: 'Fire🔥', noteRefs: [ buildRef({ collectionKey: 'notes', roomId: 'https://www.eweser.com|abc123', documentId: '0', authServer: 'https://www.eweser.com', }), ], _ref: buildRef({ collectionKey: 'flashcards', roomId: 'https://www.eweser.com|abc123', documentId: '0', authServer: 'https://www.eweser.com', }), _id: 'noteID', _created: 1653135317729, _updated: 1653135317729, }, }, }; //** to conceptualize DB shape */ const _exampleDb: { collections: Collections } = { collections: { notes: { // Rooms ['my_study_notes']: new Room({ db, collectionKey: 'notes', name: 'My Study Notes', ydoc: myStudyNotesYDoc as unknown as YDoc<Note>, }), }, flashcards: { ['typescript_study_cards']: new Room({ db, collectionKey: 'flashcards', name: 'Typescript Study Flashcards', ydoc: typescriptFlashcardsYDoc as unknown as YDoc<Flashcard>, }), ['chinese_flashcards']: new Room({ db, collectionKey: 'flashcards', name: 'Chinese Study Flashcards', ydoc: chineseFlashcardsYDoc as unknown as YDoc<Flashcard>, }), }, profiles: { ['public']: new Room({ db, collectionKey: 'profiles', name: 'Public Profile', ydoc: profileYDoc as unknown as YDoc<Profile>, }), ['private']: new Room({ db, collectionKey: 'profiles', name: 'Private Profile', ydoc: profilePrivateYDoc as unknown as YDoc<Profile>, }), }, agentConfigs: {}, agentAccessLogs: {}, conversations: {}, }, }; /** V2, drafts for y-sweet control flow: */ /**AUTH SERVER MODEL */ /** * A room is a folder or a collection of documents. It is a place where documents are stored. access permissions are set at the room level. */ const _room = new Room({ db, id: 'uuid', name: 'room_name', collectionKey: 'flashcards', // CollectionKey tokenExpiry: '12-12-12', syncUrl: 'wss://sync.example.com', publicAccess: 'private', //"private" | "read" | "write" // if read or write will invite all aggregators. readAccess: ['userId', 'AUTH_SERVER_DOMAIN'], // auth server if just for personal use, more (aggregators) if public writeAccess: ['userId', 'AUTH_SERVER_DOMAIN'], // auth server if just for personal use, more (other users) if shared writable adminAccess: ['userId'], // generally only user has admin but could give uring sharing createdAt: '12-12-12', updatedAt: '12-12-12', _deleted: false, _ttl: null, // '12-12-12' if deleted, indexedDbProvider: null, webRtcProvider: null, syncProvider: null, ydoc: null, }); export const _jwt = { id: 'jwt_id', access_record_id: '<user_id>|<requester_id>', owner_id: 'user_id', requester_id: 'requester_app_domain or requester_user_server_id', requester_type: "enum 'app' 'user'", created: 'date', updated: 'date', expires: 'date', keep_alive_days: 'number', // auto renew, extend expiry date by x days every time token is used }; /** * generate on signup (give db access to an app). used to create the access token jwt * can only update from the auth server website. * basically what is inside the jwt... except for the room_ids array which might be a bit too large for a jwt. * after an app is permissioned by the user, they use the jwt to quickly access this access_grant from the db, and make a join call for all the room.tokens, room.names, and room.collection_keys for any room_ids in the access_grant. * The access grant has some duplicate data from the room table, but it is necessary to have it in one place for quick access. * make helper functions that update the access_grant and room tables at the same time. */ export const access_grant = { id: '<user_id>|<requester_id>', is_valid: 'boolean', // use to revoke an existing jwt, although it is better to just create a new jwt room_ids: 'enum array string[]', // jwt info: owner_id: 'user_id', requester_id: 'requester_app_domain or requester_user_server_id', requester_type: "enum 'app' 'user'", jwt_id: 'jwt_id', created: 'date', updated: 'date', expires: 'date', keep_alive_days: 'number', // auto renew, extend expiry date by x days every time token is used // validate url to make sure it isnt too long like over 200 chars // requester_user_id: '<https://authserver.com>|<user_id>', // requester_app_domain: 'app.com', };