Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions packages/objectloader2/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,23 @@ The aim is to speed up random access while still getting items from the cache in

## Loader options

### Query string parameters

These can be use via a query string parameter. For example: `https://app.speckle.systems/projects/57bbfabd80/models/81b8d76ef1` can have debug logging enabled with: `https://app.speckle.systems/projects/57bbfabd80/models/81b8d76ef1?debug=true`

Current parameters:

| Parameter | Default | Type |
| ---------- | ------- | ------- |
| `debug` | `false` | boolean |
| `useCache` | `true` | boolean |
| Parameter | Default | Type | Description |
| ---------- | ------- | ------- | ----------------------------------------------------------------------------------- |
| `debug` | `false` | boolean | Enables debug logging |
| `useCache` | `true` | boolean | Uses a memory backed cache instead of Indexed DB. This can result in high RAM usage |

### Factory parameters

Current parameters:

| Parameter | Default | Type | Description |
| -------------- | ------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `debug` | `false` | boolean | Enables debug logging |
| `useCache` | `true` | boolean | Uses a memory backed cache instead of Indexed DB. This can result in high RAM usage |
| `useGetObject` | `true` | boolean | Disabling this disables caching and deferment all together. If the only usage is the getObject loop, then this saves memory by not having to randomly access the model |
5 changes: 5 additions & 0 deletions packages/objectloader2/src/core/objectLoader2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export class ObjectLoader2 {
#cacheWriter: CacheWriter

#deferments: Deferment
#useGetObject: boolean

#gathered: AsyncGeneratorQueue<Item>

Expand All @@ -31,6 +32,7 @@ export class ObjectLoader2 {

constructor(options: ObjectLoader2Options) {
this.#rootId = options.rootId
this.#useGetObject = options.useGetObject ?? true
this.#logger = options.logger || ((): void => {})
this.#logger('ObjectLoader2 initialized with rootId:', this.#rootId)

Expand Down Expand Up @@ -89,6 +91,9 @@ export class ObjectLoader2 {
}

async getObject(params: { id: string }): Promise<Base> {
if (!this.#useGetObject) {
throw new Error('getObject is disabled')
}
return await this.#cacheReader.getObject({ id: params.id })
}

Expand Down
105 changes: 65 additions & 40 deletions packages/objectloader2/src/core/objectLoader2Factory.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import { DefermentManager, MemoryOnlyDeferment } from '../deferment/defermentManager.js'
import { Deferment, DefermentManager } from '../deferment/defermentManager.js'
import { MemoryOnlyDeferment } from '../deferment/MemoryOnlyDeferment.js'
import { DisabledDeferment } from '../deferment/DisabledDeferment.js'
import {
CustomLogger,
Fetcher,
getFeatureFlag,
ObjectLoader2Flags
} from '../types/functions.js'
import { Base, ObjectAttributeMask } from '../types/types.js'
import { Database } from './interfaces.js'
import { ObjectLoader2 } from './objectLoader2.js'
import { IndexedDatabase } from './stages/indexedDatabase.js'
import { MemoryDatabase } from './stages/memory/memoryDatabase.js'
Expand All @@ -20,9 +23,20 @@ export interface ObjectLoader2FactoryOptions {
attributeMask?: ObjectAttributeMask
useCache?: boolean
debug?: boolean
useGetObject?: boolean //defaults to true
logger?: CustomLogger
}

export interface ObjectLoader2FactoryParams {
serverUrl: string
streamId: string
objectId: string
token?: string
headers?: Headers
options?: ObjectLoader2FactoryOptions
attributeMask?: ObjectAttributeMask
}

export class ObjectLoader2Factory {
static createFromObjects(objects: Base[]): ObjectLoader2 {
const root = objects[0]
Expand All @@ -44,44 +58,13 @@ export class ObjectLoader2Factory {
return this.createFromObjects(jsonObj)
}

static createFromUrl(params: {
serverUrl: string
streamId: string
objectId: string
token?: string
headers?: Headers
options?: ObjectLoader2FactoryOptions
attributeMask?: ObjectAttributeMask
}): ObjectLoader2 {
const log = ObjectLoader2Factory.getLogger(params.options?.logger)
let database
if (
params.options?.debug === true ||
getFeatureFlag(ObjectLoader2Flags.DEBUG) === 'true'
) {
this.logger('Using DEBUG mode for ObjectLoader2Factory')
}
const useCache = params.options?.useCache ?? true
const flag = getFeatureFlag(ObjectLoader2Flags.USE_CACHE)
const flagAllowsCache = flag !== 'false'

if (useCache && flagAllowsCache) {
database = new IndexedDatabase({
indexedDB: params.options?.indexedDB,
keyRange: params.options?.keyRange
})
} else {
database = new MemoryDatabase({
items: new Map<string, Base>()
})
this.logger(
'Disabled persistent caching for ObjectLoader2. Using MemoryDatabase'
)
}
const logger = log || (((): void => {}) as CustomLogger)
static createFromUrl(params: ObjectLoader2FactoryParams): ObjectLoader2 {
const logger = this.getLogger(params.options?.logger)
const database = this.getDatabase(params)
const deferments = this.getDeferment(params, logger)
const loader = new ObjectLoader2({
rootId: params.objectId,
deferments: new DefermentManager(logger),
deferments,
downloader: new ServerDownloader({
serverUrl: params.serverUrl,
streamId: params.streamId,
Expand All @@ -93,19 +76,61 @@ export class ObjectLoader2Factory {
logger
}),
database,
logger
logger,
useGetObject: params.options?.useGetObject
})
return loader
}

static getLogger(providedLogger?: CustomLogger): CustomLogger | undefined {
static getLogger(providedLogger?: CustomLogger): CustomLogger {
if (getFeatureFlag(ObjectLoader2Flags.DEBUG) === 'true') {
return providedLogger || this.logger
}
return providedLogger
return providedLogger || (((): void => {}) as CustomLogger)
}

static logger: CustomLogger = (m?: string, ...optionalParams: unknown[]) => {
console.log(`[debug] ${m}`, ...optionalParams)
}

static getDatabase(params: ObjectLoader2FactoryParams): Database {
if (
params.options?.debug === true ||
getFeatureFlag(ObjectLoader2Flags.DEBUG) === 'true'
) {
this.logger('Using DEBUG mode for ObjectLoader2Factory')
}
const useCache = params.options?.useCache ?? true
const flag = getFeatureFlag(ObjectLoader2Flags.USE_CACHE)
const flagAllowsCache = flag !== 'false'

if (useCache && flagAllowsCache) {
return new IndexedDatabase({
indexedDB: params.options?.indexedDB,
keyRange: params.options?.keyRange
})
} else {
return new MemoryDatabase({
items: new Map<string, Base>()
})
this.logger(
'Disabled persistent caching for ObjectLoader2. Using MemoryDatabase'
)
}
}

static getDeferment(
params: ObjectLoader2FactoryParams,
logger: CustomLogger
): Deferment {
const useGetObject = params.options?.useGetObject ?? true

if (useGetObject) {
logger('Using cached deferment for ObjectLoader2Factory')
return new DefermentManager(logger)
} else {
logger('Disabled caching for ObjectLoader2. Using MemoryOnlyDeferment')
return new DisabledDeferment()
}
}
}
1 change: 1 addition & 0 deletions packages/objectloader2/src/core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ObjectLoader2Options {
downloader: Downloader
database: Database
logger?: CustomLogger
useGetObject?: boolean //defaults to true
}

export interface CacheOptions {
Expand Down
Loading
Loading