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 { ID } from 'appwrite'
|
||||||
import type { Writable } from 'svelte/store'
|
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 {
|
class Collection {
|
||||||
constructor(protected databaseId: string, protected collectionId: string) { }
|
constructor(protected databaseId: string, protected collectionId: string) { }
|
||||||
|
|
||||||
|
@ -121,16 +20,105 @@ class Collection {
|
||||||
}
|
}
|
||||||
|
|
||||||
createObserver() {
|
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[] = []) {
|
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[] = []) {
|
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 client = new Client()
|
||||||
const account = new Account(client)
|
const account = new Account(client)
|
||||||
const databases = new Databases(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 = {
|
const url = {
|
||||||
oauth: {
|
oauth: {
|
||||||
|
@ -14,4 +19,4 @@ const url = {
|
||||||
client.setEndpoint('http://localhost/v1').setProject('638871b363904655d784')
|
client.setEndpoint('http://localhost/v1').setProject('638871b363904655d784')
|
||||||
|
|
||||||
export default client
|
export default client
|
||||||
export { client, account, url, databases }
|
export { client, account, url, databases, storage, teams, functions, locale, avatars }
|
||||||
|
|
Loading…
Reference in New Issue