@speckle/objectsender
Version:
Simple API helper to serialize and send objects to the server.
161 lines (137 loc) • 3.97 kB
text/typescript
import { send, Base, type SendResult, Detach, Chunkable } from '../../index'
import { times } from '#lodash'
import { createCommit } from './utils'
interface ExampleAppWindow extends Window {
send: typeof import('../../index').send
loadData: () => Promise<void>
}
const appWindow = window as unknown as ExampleAppWindow
appWindow.send = send
const setInputValue = (
key: string,
value: string,
options?: Partial<{ valueKey: 'value' | 'textContent' }>
) => {
const { valueKey = 'value' } = options || {}
const input = document.getElementById(key) as HTMLInputElement | undefined
if (!input) {
console.error("Unexpectedly couldn't find core input: " + key)
return
}
input[valueKey] = value
}
const getInputValue = (key: string) => {
const input = document.getElementById(key) as HTMLInputElement | undefined
if (!input) {
throw new Error("Unexpectedly couldn't find core input: " + key)
}
return input.value
}
appWindow.onload = () => {
const serverUrl = localStorage.getItem('serverUrl')
const apiToken = localStorage.getItem('apiToken')
const projectId = localStorage.getItem('projectId')
if (serverUrl) {
setInputValue('serverUrl', serverUrl)
}
if (apiToken) {
setInputValue('apiToken', apiToken)
}
if (projectId) {
setInputValue('projectId', projectId)
}
}
appWindow.loadData = async () => {
const serverUrl = getInputValue('serverUrl')
const apiToken = getInputValue('apiToken')
const projectId = getInputValue('projectId')
localStorage.setItem('serverUrl', serverUrl)
localStorage.setItem('projectId', projectId)
localStorage.setItem('apiToken', apiToken)
setInputValue('result', '...', { valueKey: 'textContent' })
const obj = generateTestObject()
let res: SendResult | undefined = undefined
try {
res = await send(obj, {
serverUrl,
projectId,
token: apiToken
})
await createCommit(res, { serverUrl, projectId, token: apiToken })
} catch (e) {
const msg = e instanceof Error ? e.message : JSON.stringify(e)
setInputValue('result', msg, { valueKey: 'textContent' })
throw e
}
const objectUrl = new URL(`/projects/${projectId}/models/${res.hash}`, serverUrl)
const objectLink = objectUrl.toString()
console.log(objectLink)
setInputValue('result', objectLink, { valueKey: 'textContent' })
}
function generateTestObject() {
return new Base({
start: 'end',
primitiveArray: Array(100).fill(1),
normalObject: {
hello: 'world',
how: 'are',
you: '?',
inner: {
pasta: 'pesto',
qux: 'mux'
}
},
'@detachedValue': new RandomFoo({
'@nestedDetachedValue_1': new RandomFoo({
'@nestedDetachedValue_2': new RandomFoo({
'@nestedDetachedValue_3': new RandomFoo()
})
})
}),
'@detachedArray': [
...Array(100)
.fill(0)
.map(() => new RandomFoo({ bar: 'baz baz baz' }))
],
detachedWithDecorator: new Collection<RandomFoo>('Collection of Foo', 'Foo', [
...Array(10)
.fill(0)
.map(() => new RandomFoo())
]),
'@(10)chunkedArr': times(100, () => 42),
some: new RandomJoe(),
nothing: null
})
}
class RandomFoo extends Base {
constructor(props?: Record<string, unknown>) {
super(props)
this.noise = Math.random().toString(16)
}
}
class RandomJoe extends Base {
()
(10)
numbers: number[]
constructor(props?: Record<string, unknown>) {
super(props)
this.numbers = times(100, () => 42)
}
}
export class Collection<T extends Base> extends Base {
()
elements: T[]
// eslint-disable-next-line camelcase
speckle_type = 'Speckle.Core.Models.Collection'
constructor(
name: string,
collectionType: string,
elements: T[] = [],
props?: Record<string, unknown>
) {
super(props)
this.name = name
this.collectionType = collectionType
this.elements = elements
}
}