Files observing
This commit is contained in:
parent
016bf32083
commit
0224b1ff8d
|
@ -4,107 +4,6 @@ import { Models, Query, RealtimeResponseEvent } from 'appwrite'
|
|||
import { ID } from 'appwrite'
|
||||
import type { Writable } from 'svelte/store'
|
||||
|
||||
const subscribeUpdate = (databaseId: string, collectionId: string, store: Writable<Models.Document[]>, document: Models.Document) => {
|
||||
client.subscribe(`databases.${databaseId}.collections.${collectionId}.documents.${document.$id}`, (response: RealtimeResponseEvent<any>) => {
|
||||
|
||||
if (response.events.includes(`databases.${databaseId}.collections.${collectionId}.documents.${document.$id}.delete`)) {
|
||||
store.update(current => {
|
||||
current.splice(current.indexOf(document), 1)
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (response.events.includes(`databases.${databaseId}.collections.${collectionId}.documents.${document.$id}.update`)) {
|
||||
store.update(current => {
|
||||
current[current.indexOf(document)] = response.payload
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
const subscribeInsert = (databaseId: string, collectionId: string, store: Writable<Models.Document[]>) => {
|
||||
client.subscribe(`databases.${databaseId}.collections.${collectionId}.documents`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`databases.${databaseId}.collections.${collectionId}.documents.*.create`)) {
|
||||
let lastIndex = 0
|
||||
|
||||
store.update(current => {
|
||||
current.push(response.payload)
|
||||
lastIndex = current.length - 1
|
||||
return current
|
||||
})
|
||||
|
||||
subscribeUpdate(databaseId, collectionId, store, response.payload)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe collection insert
|
||||
* @param databaseId
|
||||
* @param collectionId
|
||||
* @returns
|
||||
*/
|
||||
const observe = (databaseId: string, collectionId: string) => {
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
subscribeInsert(databaseId, collectionId, dataStore)
|
||||
return { subscribe: dataStore.subscribe }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Subscribe collection update, delete
|
||||
* @param databaseId
|
||||
* @param collectionId
|
||||
* @param queries
|
||||
* @returns
|
||||
*/
|
||||
const subscribe = (databaseId: string, collectionId: string, queries: string[]) => {
|
||||
const loadingStore = writable(true)
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
|
||||
databases.listDocuments(databaseId, collectionId, queries).then(data => {
|
||||
data.documents.forEach((document) => subscribeUpdate(databaseId, collectionId, dataStore, document))
|
||||
|
||||
dataStore.set(data.documents)
|
||||
loadingStore.set(false)
|
||||
})
|
||||
|
||||
return [{ subscribe: dataStore.subscribe }, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
|
||||
/**
|
||||
* Paginate collection
|
||||
* @param databaseId
|
||||
* @param collectionId
|
||||
* @param limit
|
||||
* @returns
|
||||
*/
|
||||
const paginate = (databaseId: string, collectionId: string, limit: number, queries: string[] = []) => {
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
const loadingStore = writable(true)
|
||||
let offset = 0
|
||||
|
||||
const store = {
|
||||
subscribe: dataStore.subscribe,
|
||||
async next() {
|
||||
await databases.listDocuments(databaseId, collectionId, [...queries, Query.limit(limit), Query.offset(offset)]).then(data => {
|
||||
data.documents.forEach((document) => subscribeUpdate(databaseId, collectionId, dataStore, document))
|
||||
|
||||
dataStore.update(current => [...current, ...data.documents])
|
||||
offset += limit
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
store.next().then(() => loadingStore.set(false))
|
||||
|
||||
return [store, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
|
||||
class Collection {
|
||||
constructor(protected databaseId: string, protected collectionId: string) { }
|
||||
|
||||
|
@ -121,16 +20,105 @@ class Collection {
|
|||
}
|
||||
|
||||
createObserver() {
|
||||
return observe(this.databaseId, this.collectionId)
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
|
||||
client.subscribe(`databases.${this.databaseId}.collections.${this.collectionId}.documents`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`databases.${this.databaseId}.collections.${this.collectionId}.documents.*.create`)) {
|
||||
dataStore.update(current => {
|
||||
current.push(response.payload)
|
||||
return current
|
||||
})
|
||||
|
||||
this.subscribeCollectionUpdate(response.payload, dataStore)
|
||||
}
|
||||
})
|
||||
|
||||
return { subscribe: dataStore.subscribe }
|
||||
}
|
||||
|
||||
createSubscriber(queries: string[] = []) {
|
||||
return subscribe(this.databaseId, this.collectionId, queries)
|
||||
const loadingStore = writable(true)
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
|
||||
databases.listDocuments(this.databaseId, this.collectionId, queries).then(data => {
|
||||
data.documents.forEach((document) => this.subscribeCollectionUpdate(document, dataStore))
|
||||
|
||||
dataStore.set(data.documents)
|
||||
loadingStore.set(false)
|
||||
})
|
||||
|
||||
return [{ subscribe: dataStore.subscribe }, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
|
||||
createPaginate(limit: number, queries: string[] = []) {
|
||||
return paginate(this.databaseId, this.collectionId, limit, queries)
|
||||
const dataStore = writable<Models.Document[]>([])
|
||||
const loadingStore = writable(true)
|
||||
let offset = 0
|
||||
|
||||
const store = {
|
||||
subscribe: dataStore.subscribe,
|
||||
async next() {
|
||||
await databases.listDocuments(this.databaseId, this.collectionId, [...queries, Query.limit(limit), Query.offset(offset)]).then(data => {
|
||||
data.documents.forEach((document) => this.subscribeCollectionUpdate(document, dataStore))
|
||||
|
||||
dataStore.update(current => [...current, ...data.documents])
|
||||
offset += limit
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default Collection
|
||||
store.next().then(() => loadingStore.set(false))
|
||||
|
||||
return [store, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
|
||||
protected subscribeCollectionUpdate(document: Models.Document, store: Writable<Models.Document[]>) {
|
||||
client.subscribe(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${document.$id}`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${document.$id}.delete`)) {
|
||||
store.update(current => {
|
||||
current.splice(current.indexOf(document), 1)
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (response.events.includes(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${document.$id}.update`)) {
|
||||
store.update(current => {
|
||||
current[current.indexOf(document)] = response.payload
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class Document {
|
||||
constructor(protected databaseId: string, protected collectionId: string, protected documentId: string) { }
|
||||
|
||||
createSubscriber() {
|
||||
const dataStore = writable<Models.Document>(null)
|
||||
const loadingStore = writable(true)
|
||||
|
||||
databases.getDocument(this.databaseId, this.collectionId, this.documentId).then(data => {
|
||||
dataStore.set(data)
|
||||
loadingStore.set(false)
|
||||
})
|
||||
|
||||
client.subscribe(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${this.documentId}`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${this.documentId}.update`)) {
|
||||
dataStore.set(response.payload)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.events.includes(`databases.${this.databaseId}.collections.${this.collectionId}.documents.${this.documentId}.delete`)) {
|
||||
dataStore.set(null)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
return [{ subscribe: dataStore.subscribe }, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
}
|
||||
|
||||
export { Collection, Document }
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
import { storage, client } from './stores/appwrite'
|
||||
import { ID, Models, RealtimeResponseEvent } from 'appwrite'
|
||||
import { Writable, writable } from 'svelte/store'
|
||||
|
||||
class Storage {
|
||||
constructor(protected bucketId: string) { }
|
||||
|
||||
createFile(file, permissions: string[] = []) {
|
||||
return storage.createFile(this.bucketId, ID.unique(), file, permissions)
|
||||
}
|
||||
|
||||
deleteFile(fileId: string) {
|
||||
return storage.deleteFile(this.bucketId, fileId)
|
||||
}
|
||||
|
||||
updateFile(fileId: string, permissions: string[] = []) {
|
||||
return storage.updateFile(this.bucketId, fileId, permissions)
|
||||
}
|
||||
|
||||
createUploadDispatcher(acceptManyFiles = false) {
|
||||
return (node: HTMLInputElement) => {
|
||||
const eventListener = (e) => {
|
||||
const files = acceptManyFiles ? e.target.files : [e.target.files[0]]
|
||||
files.forEach((file) => this.createFile(file))
|
||||
}
|
||||
|
||||
node.addEventListener('change', eventListener)
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
node.removeEventListener('change', eventListener)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createSubsciber(queries: string[] = [], search = '') {
|
||||
const filesStore = writable<Models.File[]>([])
|
||||
const loadingStore = writable(true)
|
||||
|
||||
storage.listFiles(this.bucketId, queries, search).then(files => {
|
||||
for (const file of files.files) {
|
||||
this.subscribeFileUpdate(file, filesStore)
|
||||
}
|
||||
})
|
||||
|
||||
return [{ subscribe: filesStore.subscribe }, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
|
||||
createObserver() {
|
||||
const dataStore = writable<Models.File[]>([])
|
||||
|
||||
client.subscribe(`buckets.${this.bucketId}.files`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`buckets.${this.bucketId}.files.*.create`)) {
|
||||
dataStore.update(current => {
|
||||
current.push(response.payload)
|
||||
return current
|
||||
})
|
||||
|
||||
this.subscribeFileUpdate(response.payload, dataStore)
|
||||
}
|
||||
})
|
||||
|
||||
return { subscribe: dataStore.subscribe }
|
||||
}
|
||||
|
||||
protected subscribeFileUpdate(file: Models.File, filesStore: Writable<Models.File[]>) {
|
||||
client.subscribe(`buckets.${this.bucketId}.files.${file.$id}`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`buckets.${this.bucketId}.files.${file.$id}.update`)) {
|
||||
filesStore.update(current => {
|
||||
current[current.indexOf(file)] = file
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (response.events.includes(`buckets.${this.bucketId}.files.${file.$id}.delete`)) {
|
||||
filesStore.update(current => {
|
||||
current.splice(current.indexOf(file), 1)
|
||||
return current
|
||||
})
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class File {
|
||||
constructor(protected bucketId: string, protected fileId: string) { }
|
||||
|
||||
createSubscriber() {
|
||||
const fileStore = writable<Models.File>(null)
|
||||
const loadingStore = writable(true)
|
||||
|
||||
storage.getFile(this.bucketId, this.fileId).then((result) => {
|
||||
fileStore.set(result)
|
||||
loadingStore.set(false)
|
||||
})
|
||||
|
||||
client.subscribe(`buckets.${this.bucketId}.files.${this.fileId}`, (response: RealtimeResponseEvent<any>) => {
|
||||
if (response.events.includes(`buckets.${this.bucketId}.files.${this.fileId}.update`)) {
|
||||
fileStore.set(response.payload)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.events.includes(`buckets.${this.bucketId}.files.${this.fileId}.delete`)) {
|
||||
fileStore.set(null)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
return [{ subscribe: fileStore.subscribe }, { subscribe: loadingStore.subscribe }] as const
|
||||
}
|
||||
}
|
||||
|
||||
export { Storage, File }
|
|
@ -1,8 +1,13 @@
|
|||
import { Client, Account, Databases } from 'appwrite'
|
||||
import { Client, Account, Databases, Storage, Teams, Functions, Locale, Avatars } from 'appwrite'
|
||||
|
||||
const client = new Client()
|
||||
const account = new Account(client)
|
||||
const databases = new Databases(client)
|
||||
const storage = new Storage(client)
|
||||
const teams = new Teams(client)
|
||||
const functions = new Functions(client)
|
||||
const locale = new Locale(client)
|
||||
const avatars = new Avatars(client)
|
||||
|
||||
const url = {
|
||||
oauth: {
|
||||
|
@ -14,4 +19,4 @@ const url = {
|
|||
client.setEndpoint('http://localhost/v1').setProject('638871b363904655d784')
|
||||
|
||||
export default client
|
||||
export { client, account, url, databases }
|
||||
export { client, account, url, databases, storage, teams, functions, locale, avatars }
|
||||
|
|
Loading…
Reference in New Issue