Offline Object Loader (#3717)

* Quick hack to demo how an offline loader would work with as little complication as possible

* Further simplified yielding objects in offline mode

* Commented out the URL thing

* Implemented SpeckleOfflineLoader. JSON parsing is implemented at object-loader level, completely isolated from the rest of the implementation in order to avoid regression

* Isolated ObjectLoader creation in base SpeckleLoader class so any extended classes can overwrite the way the object loader is created and used

* Removed the big json sample file

* Updated version

* Removed unused functions from objectloader

* Restored viewer package version

* Fixed typo

* Renamed and moved the sample offline Speckle JSON

* Replaced the default JSON object sample with a much smaller one since we don't want to increase the sandbox's build size by 10 megs

* Fixed a linting error
This commit is contained in:
Alexandru Popovici
2024-12-18 17:21:13 +02:00
committed by GitHub
parent d3a10e4bec
commit 6fc7c06e9c
8 changed files with 156 additions and 15 deletions
+68
View File
@@ -107,6 +107,69 @@ class ObjectLoader {
}
}
static createFromJSON(json) {
const start = performance.now()
const jsonObj = JSON.parse(json)
console.warn('JSON Parse Time -> ', performance.now() - start)
const rootObject = jsonObj[0]
const loader = new (class extends ObjectLoader {
constructor() {
super({
serverUrl: 'dummy',
streamId: 'dummy',
undefined,
objectId: rootObject.id
})
this.objectId = rootObject.id
}
async getRootObject() {
return rootObject
}
async getTotalObjectCount() {
return Object.keys(rootObject?.__closure || {}).length
}
async *getObjectIterator() {
const t0 = Date.now()
let count = 0
for await (const { id, obj } of this.getRawObjectIterator(jsonObj)) {
this.buffer[id] = obj
count += 1
yield obj
}
this.logger(`Loaded ${count} objects in: ${(Date.now() - t0) / 1000}`)
}
async *getRawObjectIterator(data) {
yield { id: data[0].id, obj: data[0] }
const rootObj = data[0]
if (!rootObj.__closure) return
// const childrenIds = Object.keys(rootObj.__closure)
// .filter((id) => !id.includes('blob'))
// .sort((a, b) => rootObj.__closure[a] - rootObj.__closure[b])
// for (const id of childrenIds) {
// const obj = data.find((value) => value.id === id)
// // Sleep 1 ms
// await new Promise((resolve) => {
// setTimeout(resolve, 1)
// })
// yield { id, obj }
// }
for (const item of data) {
yield { id: item.id, obj: item }
}
}
})()
return loader
}
async asyncPause() {
// Don't freeze the UI
// while ( this.existingAsyncPause ) {
@@ -140,6 +203,11 @@ class ObjectLoader {
return totalChildrenCount
}
async getRootObject() {
const rootObjJson = await this.getRawRootObject()
return JSON.parse(rootObjJson)
}
/**
* Use this method to receive and construct the object. It will return the full, de-referenced and de-chunked original object.
* @param {*} onProgress
+2
View File
@@ -41,6 +41,8 @@ class ObjectLoader {
}>
})
static createFromJSON(input: string): ObjectLoader
async getRootObject(): Promise<SpeckleObject>
async getTotalObjectCount(): Promise<number>
async getAndConstructObject(
onProgress: (e: { stage: ProgressStage; current: number; total: number }) => void