Fix the dangling promises

This commit is contained in:
Aria Minaei 2023-08-03 10:46:36 +02:00
parent 27f918f53c
commit 041627f7e4
19 changed files with 112 additions and 67 deletions

View file

@ -66,6 +66,7 @@ module.exports = {
},
],
'@typescript-eslint/no-unused-vars': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
},
},
{

View file

@ -106,6 +106,6 @@ async function test1() {
iterateOnSequence()
}
test1().then(() => {
void test1().then(() => {
console.log('test1 done')
})

View file

@ -35,14 +35,14 @@ function createBundles(watch: boolean) {
// format: 'iife',
// })
build({
void build({
...esbuildConfig,
entryPoints: [path.join(pathToPackage, 'src/core-and-studio.ts')],
outfile: path.join(pathToPackage, 'dist/core-and-studio.js'),
format: 'iife',
})
build({
void build({
...esbuildConfig,
entryPoints: [path.join(pathToPackage, 'src/core-only.ts')],
outfile: path.join(pathToPackage, 'dist/core-only.min.js'),

View file

@ -17,7 +17,7 @@ function createBundles(watch: boolean) {
conditions: ['browser', 'node'],
}
build({
void build({
...esbuildConfig,
outfile: path.join(pathToPackage, 'dist/index.js'),
format: 'cjs',

View file

@ -53,7 +53,7 @@ const ImageTypeExample: React.FC<{}> = (props) => {
onClick={() => {
if (sheet.sequence.position === 0) {
sheet.sequence.position = 0
sheet.sequence.play()
void sheet.sequence.play()
} else {
sheet.sequence.position = 0
}
@ -64,6 +64,10 @@ const ImageTypeExample: React.FC<{}> = (props) => {
)
}
project.ready.then(() => {
render(<ImageTypeExample />, document.getElementById('root'))
})
project.ready
.then(() => {
render(<ImageTypeExample />, document.getElementById('root'))
})
.catch((err) => {
console.error(err)
})

View file

@ -7,7 +7,7 @@ import {Scene} from './Scene'
studio.initialize()
// trigger warning notification
getProject('Sample project').sheet('Scene').sequence.play()
void getProject('Sample project').sheet('Scene').sequence.play()
// fire an info notification
notify.info(
@ -16,7 +16,7 @@ notify.info(
'(and all others) at the start of index.tsx. You can also see examples of success and warnign notifications.',
)
getProject('Sample project').ready.then(() => {
void getProject('Sample project').ready.then(() => {
// fire a success notification on project load
notify.success(
'Project loaded!',

View file

@ -3,7 +3,7 @@ import {render} from 'react-dom'
import React, {useState} from 'react'
import state from './state.json'
initialize({state})
void initialize({state})
function SomeComponent({id}: {id: string}) {
const {foo, $get, $set} = useControls(

View file

@ -76,7 +76,7 @@ function App() {
const bg = bgs[bgIndex]
const project = getProject('SpaceStress', {state})
const sheet = project.sheet('Scene')
project.ready.then(() => sheet.sequence.play({iterationCount: Infinity}))
void project.ready.then(() => sheet.sequence.play({iterationCount: Infinity}))
const allPropsObj = sheet.object('All Props Tester', allPropsObjectConfig)
console.log('allPropsObj', allPropsObj)

View file

@ -39,13 +39,13 @@ const elements = new Array(TOTAL_ELEMENTS).fill(0).map((_, idx) => {
return {el, sheet, obj}
})
project.ready.then(() => {
void project.ready.then(() => {
// select the playback controls obj so it shows as a tweakable control
studio.setSelection([playbackControlObj])
for (let i = 0; i < elements.length; i++) {
const sheet = elements[i].sheet
sheet.sequence.position = i * TOTAL_ELEMENTS_R * 5
sheet.sequence.play({
void sheet.sequence.play({
iterationCount: Infinity,
})
}

View file

@ -8,11 +8,10 @@ const definedGlobals = {
'process.env.NODE_ENV': JSON.stringify('production'),
}
createBundles()
void createBundles()
async function createBundles() {
createMainBundle()
createExtensionBundle()
await Promise.all([createMainBundle(), createExtensionBundle()])
async function createMainBundle() {
const pathToEntry = path.join(__dirname, '../src/index.ts')

View file

@ -24,7 +24,7 @@ const definedGlobals = {
global: 'window',
}
function createBundles(watch: boolean) {
async function createBundles(watch: boolean) {
const pathToPackage = path.join(__dirname, '../')
const esbuildConfig: Parameters<typeof build>[0] = {
entryPoints: [path.join(pathToPackage, 'src/index.ts')],
@ -39,7 +39,7 @@ function createBundles(watch: boolean) {
plugins: [externalPlugin([/^[\@a-zA-Z]+/])],
}
build({
await build({
...esbuildConfig,
outfile: path.join(pathToPackage, 'dist/index.js'),
format: 'cjs',
@ -52,4 +52,4 @@ function createBundles(watch: boolean) {
// })
}
createBundles(false)
void createBundles(false)

View file

@ -24,7 +24,7 @@ const definedGlobals = {
global: 'window',
}
function createBundles(watch: boolean) {
async function createBundles(watch: boolean) {
const pathToPackage = path.join(__dirname, '../')
const pkgJson = require(path.join(pathToPackage, 'package.json'))
const listOfDependencies = Object.keys(pkgJson.dependencies || {})
@ -52,7 +52,7 @@ function createBundles(watch: boolean) {
],
}
build({
await build({
...esbuildConfig,
outfile: path.join(pathToPackage, 'dist/index.js'),
format: 'cjs',
@ -65,4 +65,4 @@ function createBundles(watch: boolean) {
// })
}
createBundles(false)
void createBundles(false)

View file

@ -196,29 +196,34 @@ export default class Project {
}
this._studio = studio
studio.initialized.then(async () => {
await initialiseProjectState(studio, this, this.config.state)
studio.initialized
.then(async () => {
await initialiseProjectState(studio, this, this.config.state)
this._pointerProxies.historic.setPointer(
studio.atomP.historic.coreByProject[this.address.projectId],
)
this._pointerProxies.ahistoric.setPointer(
studio.atomP.ahistoric.coreByProject[this.address.projectId],
)
this._pointerProxies.ephemeral.setPointer(
studio.atomP.ephemeral.coreByProject[this.address.projectId],
)
this._pointerProxies.historic.setPointer(
studio.atomP.historic.coreByProject[this.address.projectId],
)
this._pointerProxies.ahistoric.setPointer(
studio.atomP.ahistoric.coreByProject[this.address.projectId],
)
this._pointerProxies.ephemeral.setPointer(
studio.atomP.ephemeral.coreByProject[this.address.projectId],
)
// asset storage has to be initialized after the pointers are set
studio
.createAssetStorage(this, this.config.assets?.baseUrl)
.then((assetStorage) => {
this.assetStorage = assetStorage
this._assetStorageReadyDeferred.resolve(undefined)
})
// asset storage has to be initialized after the pointers are set
await studio
.createAssetStorage(this, this.config.assets?.baseUrl)
.then((assetStorage) => {
this.assetStorage = assetStorage
this._assetStorageReadyDeferred.resolve(undefined)
})
this._studioReadyDeferred.resolve(undefined)
})
this._studioReadyDeferred.resolve(undefined)
})
.catch((err) => {
console.error(err)
throw err
})
}
get isAttachedToStudio() {

View file

@ -354,7 +354,9 @@ async function resolveAudioBuffer(args: IAttachAudioArgs): Promise<{
}
return new Promise<AudioContext>((resolve) => {
const listener = () => {
ctx.resume()
ctx.resume().catch((err) => {
console.error(err)
})
}
const eventsToHookInto: Array<keyof WindowEventMap> = [
@ -412,6 +414,7 @@ async function resolveAudioBuffer(args: IAttachAudioArgs): Promise<{
const audioContext = await audioContextPromise
// eslint-disable-next-line @typescript-eslint/no-floating-promises
audioContext.decodeAudioData(
arrayBuffer,
decodedBufferDeferred.resolve,

View file

@ -1,3 +1,3 @@
import {createBundles} from './createBundles'
createBundles(false)
void createBundles(false)

View file

@ -1,3 +1,3 @@
import {createBundles} from './createBundles'
createBundles(true)
void createBundles(true)

View file

@ -28,7 +28,7 @@ const defaultProps = {
let lastProjectN = 0
const studio = getStudio()!
studio.initialize({usePersistentStorage: false})
void studio.initialize({usePersistentStorage: false})
export async function setupTestSheet(sheetState: SheetState_Historic) {
const projectState: ProjectState_Historic = {

View file

@ -203,7 +203,9 @@ export class Studio {
if (process.env.NODE_ENV !== 'test') {
this.ui.render()
checkForUpdates()
checkForUpdates().catch((err) => {
console.error(err)
})
}
}
@ -266,7 +268,7 @@ export class Studio {
return this._coreAtom.pointer.core
}
extend(extension: IExtension) {
extend(extension: IExtension, opts?: {__experimental_reconfigure?: boolean}) {
if (!extension || typeof extension !== 'object') {
throw new Error(`Extensions must be JS objects`)
}
@ -275,20 +277,27 @@ export class Studio {
throw new Error(`extension.id must be a string`)
}
const reconfigure = opts?.__experimental_reconfigure === true
const extensionId = extension.id
const prevExtension =
this._store.getState().ephemeral.extensions.byId[extensionId]
if (prevExtension) {
if (
extension === prevExtension ||
shallowEqual(extension, prevExtension)
) {
// probably running studio.extend() several times because of hot reload.
// as long as it's the same extension, we can safely ignore.
return
if (reconfigure) {
} else {
if (
extension === prevExtension ||
shallowEqual(extension, prevExtension)
) {
// probably running studio.extend() several times because of hot reload.
// as long as it's the same extension, we can safely ignore.
return
}
throw new Error(
`Extension id "${extension.id}" is already defined. If you mean to re-configure the extension, do it like this: studio.extend(extension, {__experimental_reconfigure: true})})`,
)
}
throw new Error(`Extension id "${extension.id}" is already defined`)
}
this.transaction(({drafts}) => {
@ -296,6 +305,14 @@ export class Studio {
const allPaneClasses = drafts.ephemeral.extensions.paneClasses
if (reconfigure && prevExtension) {
// remove all pane classes that were set by the previous version of the extension
prevExtension.panes?.forEach((classDefinition) => {
delete allPaneClasses[classDefinition.class]
})
}
// if the extension defines pane classes, add them to the list of all pane classes
extension.panes?.forEach((classDefinition) => {
if (typeof classDefinition.class !== 'string') {
throw new Error(`pane.class must be a string`)
@ -309,9 +326,16 @@ export class Studio {
const existing = allPaneClasses[classDefinition.class]
if (existing) {
throw new Error(
`Pane class "${classDefinition.class}" already exists and is supplied by extension ${existing}`,
)
if (reconfigure && existing.extensionId === extension.id) {
// well this should never happen because we already deleted the pane class above
console.warn(
`Pane class "${classDefinition.class}" already exists. This is a bug in Theatre.js. Please report it at https://github.com/theatre-js/theatre/issues/new`,
)
} else {
throw new Error(
`Pane class "${classDefinition.class}" already exists and is supplied by extension ${existing}`,
)
}
}
allPaneClasses[classDefinition.class] = {

View file

@ -24,9 +24,14 @@ export default class UI {
}
this._rendered = true
this._nonSSRBits.then((b) => {
b.render()
})
this._nonSSRBits
.then((b) => {
b.render()
})
.catch((err) => {
console.error(err)
throw err
})
}
hide() {
@ -53,10 +58,14 @@ export default class UI {
let unmount: null | (() => void) = null
this._nonSSRBits.then((nonSSRBits) => {
if (shouldUnmount) return // unmount requested before the toolset is mounted, so, abort
unmount = nonSSRBits.renderToolset(toolsetId, htmlNode)
})
this._nonSSRBits
.then((nonSSRBits) => {
if (shouldUnmount) return // unmount requested before the toolset is mounted, so, abort
unmount = nonSSRBits.renderToolset(toolsetId, htmlNode)
})
.catch((err) => {
console.error(err)
})
return () => {
if (unmount) {