Simplify project config

This commit is contained in:
Aria Minaei 2021-06-18 20:35:01 +02:00
parent c72647c1e5
commit 39a2645d65
27 changed files with 79 additions and 87 deletions

View file

@ -26,7 +26,6 @@ require('esbuild')
sourcemap: true, sourcemap: true,
define: { define: {
global: 'window', global: 'window',
'$env.isCore': false,
...convertObjectToWebpackDefinePaths({ ...convertObjectToWebpackDefinePaths({
process: {env: envConfig}, process: {env: envConfig},
$env: envConfig, $env: envConfig,

View file

@ -5,6 +5,7 @@
"source": "src/index.tsx", "source": "src/index.tsx",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"private": "true",
"files": [ "files": [
"dist/**/*" "dist/**/*"
], ],

View file

@ -14,7 +14,7 @@ export default class CoreBundle {
} }
get version() { get version() {
return $env.version return process.env.version
} }
getBitsForStudio(studio: Studio, callback: (bits: CoreBits) => void) { getBitsForStudio(studio: Studio, callback: (bits: CoreBits) => void) {

View file

@ -5,6 +5,7 @@ import type {
IProjectConfig, IProjectConfig,
} from '@theatre/core/projects/TheatreProject' } from '@theatre/core/projects/TheatreProject'
import TheatreProject from '@theatre/core/projects/TheatreProject' import TheatreProject from '@theatre/core/projects/TheatreProject'
import globals from '@theatre/shared/globals'
import * as types from '@theatre/shared/propTypes' import * as types from '@theatre/shared/propTypes'
import {InvalidArgumentError} from '@theatre/shared/utils/errors' import {InvalidArgumentError} from '@theatre/shared/utils/errors'
import {validateName} from '@theatre/shared/utils/sanitizers' import {validateName} from '@theatre/shared/utils/sanitizers'
@ -17,13 +18,13 @@ export function getProject(id: string, config: IProjectConfig = {}): IProject {
return projectsSingleton.get(id)!.publicApi return projectsSingleton.get(id)!.publicApi
} }
if ($env.NODE_ENV === 'development') { if (process.env.NODE_ENV !== 'production') {
validateName(id, 'projectName in Theatre.getProject(projectName)', true) validateName(id, 'projectName in Theatre.getProject(projectName)', true)
validateProjectIdOrThrow(id) validateProjectIdOrThrow(id)
} }
if (config.state) { if (config.state) {
if ($env.NODE_ENV === 'development') { if (process.env.NODE_ENV !== 'production') {
shallowValidateOnDiskState(id, config.state) shallowValidateOnDiskState(id, config.state)
} else { } else {
deepValidateOnDiskState(id, config.state) deepValidateOnDiskState(id, config.state)
@ -41,7 +42,7 @@ const shallowValidateOnDiskState = (projectId: string, s: OnDiskState) => {
if ( if (
Array.isArray(s) || Array.isArray(s) ||
s == null || s == null ||
s.definitionVersion !== $env.currentProjectStateDefinitionVersion s.definitionVersion !== globals.currentProjectStateDefinitionVersion
) { ) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Error validating conf.state in Theatre.getProject(${JSON.stringify( `Error validating conf.state in Theatre.getProject(${JSON.stringify(

View file

@ -12,6 +12,7 @@ import projectsSingleton from './projectsSingleton'
import type {ProjectState} from './store/storeTypes' import type {ProjectState} from './store/storeTypes'
import type {Deferred} from '@theatre/shared/utils/defer' import type {Deferred} from '@theatre/shared/utils/defer'
import {defer} from '@theatre/shared/utils/defer' import {defer} from '@theatre/shared/utils/defer'
import globals from '@theatre/shared/globals'
export type Conf = Partial<{ export type Conf = Partial<{
state: OnDiskState state: OnDiskState
@ -55,7 +56,7 @@ export default class Project {
}, },
historic: config.state ?? { historic: config.state ?? {
sheetsById: {}, sheetsById: {},
definitionVersion: $env.currentProjectStateDefinitionVersion, definitionVersion: globals.currentProjectStateDefinitionVersion,
}, },
ephemeral: { ephemeral: {
loadingState: { loadingState: {

View file

@ -52,7 +52,7 @@ export default class TheatreProject implements IProject {
'project.sheet', 'project.sheet',
) )
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
validateName( validateName(
instanceId, instanceId,
'instanceId in project.sheet(sheetId, instanceId)', 'instanceId in project.sheet(sheetId, instanceId)',

View file

@ -3,6 +3,7 @@ import delay from '@theatre/shared/utils/delay'
import {original} from 'immer' import {original} from 'immer'
import type Project from './Project' import type Project from './Project'
import type {OnDiskState} from './store/storeTypes' import type {OnDiskState} from './store/storeTypes'
import globals from '@theatre/shared/globals'
/** /**
* @todo this could be turned into a simple derivation, like: * @todo this could be turned into a simple derivation, like:
@ -40,7 +41,7 @@ export default async function initialiseProjectState(
drafts.historic.coreByProject[projectId] = { drafts.historic.coreByProject[projectId] = {
sheetsById: {}, sheetsById: {},
definitionVersion: $env.currentProjectStateDefinitionVersion, definitionVersion: globals.currentProjectStateDefinitionVersion,
} }
} }

View file

@ -107,7 +107,7 @@ export default class Sequence {
set position(requestedPosition: number) { set position(requestedPosition: number) {
let position = requestedPosition let position = requestedPosition
this.pause() this.pause()
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
if (typeof position !== 'number') { if (typeof position !== 'number') {
logger.error( logger.error(
`value t in sequence.position = t must be a number. ${typeof position} given`, `value t in sequence.position = t must be a number. ${typeof position} given`,
@ -164,7 +164,7 @@ export default class Sequence {
end: sequenceDuration, end: sequenceDuration,
} }
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
if (typeof range.start !== 'number' || range.start < 0) { if (typeof range.start !== 'number' || range.start < 0) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument conf.range.start in sequence.play(conf) must be a positive number. ${JSON.stringify( `Argument conf.range.start in sequence.play(conf) must be a positive number. ${JSON.stringify(
@ -207,7 +207,7 @@ export default class Sequence {
const iterationCount = const iterationCount =
conf && typeof conf.iterationCount === 'number' ? conf.iterationCount : 1 conf && typeof conf.iterationCount === 'number' ? conf.iterationCount : 1
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
if ( if (
!(Number.isInteger(iterationCount) && iterationCount > 0) && !(Number.isInteger(iterationCount) && iterationCount > 0) &&
iterationCount !== Infinity iterationCount !== Infinity
@ -222,7 +222,7 @@ export default class Sequence {
const rate = conf && typeof conf.rate !== 'undefined' ? conf.rate : 1 const rate = conf && typeof conf.rate !== 'undefined' ? conf.rate : 1
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
if (typeof rate !== 'number' || rate === 0) { if (typeof rate !== 'number' || rate === 0) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument conf.rate in sequence.play(conf) must be a number larger than 0. ${JSON.stringify( `Argument conf.rate in sequence.play(conf) must be a number larger than 0. ${JSON.stringify(
@ -242,7 +242,7 @@ export default class Sequence {
const direction = conf && conf.direction ? conf.direction : 'normal' const direction = conf && conf.direction ? conf.direction : 'normal'
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
if (possibleDirections.indexOf(direction) === -1) { if (possibleDirections.indexOf(direction) === -1) {
throw new InvalidArgumentError( throw new InvalidArgumentError(
`Argument conf.direction in sequence.play(conf) must be one of ${JSON.stringify( `Argument conf.direction in sequence.play(conf) must be one of ${JSON.stringify(

View file

@ -43,7 +43,7 @@ export default class TheatreSequence {
if (privateAPI(this)._project.isReady()) { if (privateAPI(this)._project.isReady()) {
return privateAPI(this).play(conf) return privateAPI(this).play(conf)
} else { } else {
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
logger.warn( logger.warn(
`You seem to have called sequence.play() before the project has finished loading.\n` + `You seem to have called sequence.play() before the project has finished loading.\n` +
`This would **not** a problem in production when using '@theatre/core', since Theatre loads instantly in core mode. ` + `This would **not** a problem in production when using '@theatre/core', since Theatre loads instantly in core mode. ` +

View file

@ -81,7 +81,7 @@ const pp = (
const currentKeyframe = track.keyframes[currentKeyframeIndex] const currentKeyframe = track.keyframes[currentKeyframeIndex]
if (!currentKeyframe) { if (!currentKeyframe) {
if ($env.NODE_ENV === 'development') { if (process.env.NODE_ENV !== 'production') {
logger.error(`Bug here`) logger.error(`Bug here`)
} }
return states.error return states.error
@ -93,7 +93,7 @@ const pp = (
if (currentKeyframeIndex === 0) { if (currentKeyframeIndex === 0) {
return states.beforeFirstKeyframe(currentKeyframe) return states.beforeFirstKeyframe(currentKeyframe)
} else { } else {
if ($env.NODE_ENV === 'development') { if (process.env.NODE_ENV !== 'production') {
logger.error(`Bug here`) logger.error(`Bug here`)
} }
return states.error return states.error

View file

@ -180,7 +180,7 @@ export default class SheetObjectTemplate {
* Not available in core. * Not available in core.
*/ */
getMapOfValidSequenceTracks_forStudio(): IDerivation<IPropPathToTrackIdTree> { getMapOfValidSequenceTracks_forStudio(): IDerivation<IPropPathToTrackIdTree> {
if (!$env.isCore) { if (process.env.NODE_ENV !== 'production') {
return this._cache.get('getMapOfValidSequenceTracks_forStudio', () => return this._cache.get('getMapOfValidSequenceTracks_forStudio', () =>
this.getArrayOfValidSequenceTracks().map((arr) => { this.getArrayOfValidSequenceTracks().map((arr) => {
let map = {} let map = {}

32
theatre/devEnv/build.ts Normal file
View file

@ -0,0 +1,32 @@
import path from 'path'
import {
convertObjectToWebpackDefinePaths,
getEnvConfig,
} from './webpack/createWebpackConfig'
const playgroundDir = path.join(__dirname, '..')
const envConfig = getEnvConfig(true)
require('esbuild').serve(
{
port,
servedir: path.join(playgroundDir, 'src'),
},
{
entryPoints: [path.join(playgroundDir, 'src/index.tsx')],
target: ['firefox88'],
loader: {'.png': 'file'},
// outdir: '.',
// watch: true,
bundle: true,
sourcemap: true,
define: {
global: 'window',
...convertObjectToWebpackDefinePaths({
process: {env: envConfig},
'process.env': envConfig,
}),
},
},
)

View file

@ -24,7 +24,6 @@ export default (type: 'playground' | 'development' | 'production') => {
return bundles.map((which) => { return bundles.map((which) => {
const envConfig = getEnvConfig(isDev) const envConfig = getEnvConfig(isDev)
envConfig.isCore = which === 'core'
envConfig.version = require('../../package.json').version envConfig.version = require('../../package.json').version
const packageRoot = path.join( const packageRoot = path.join(
privatePackageRoot, privatePackageRoot,
@ -175,12 +174,6 @@ export default (type: 'playground' | 'development' | 'production') => {
} }
} }
if (which === 'core') {
config.plugins!.push(
new webpack.DefinePlugin({'$env.isCore': JSON.stringify(true)}),
)
}
if (!isDev) { if (!isDev) {
config.stats = { config.stats = {
// @ts-ignore // @ts-ignore
@ -196,12 +189,12 @@ export default (type: 'playground' | 'development' | 'production') => {
} }
} }
// defined process.env and $env // defined process.env and process.env
config.plugins!.push( config.plugins!.push(
new webpack.DefinePlugin( new webpack.DefinePlugin(
convertObjectToWebpackDefinePaths({ convertObjectToWebpackDefinePaths({
process: {env: envConfig}, process: {env: envConfig},
$env: envConfig, 'process.env': envConfig,
}), }),
), ),
) )

View file

@ -2,5 +2,4 @@ require('ts-node').register({transpileOnly: true, skipProject: true})
const createWebpackConfigObject = require('./createWebpackConfig') const createWebpackConfigObject = require('./createWebpackConfig')
// @ts-ignore
module.exports = createWebpackConfigObject('production') module.exports = createWebpackConfigObject('production')

36
theatre/globals.d.ts vendored
View file

@ -8,43 +8,11 @@ interface NodeModule {
} }
} }
// First, the env variables that exist regardless of the value of NODE_ENV interface ProcessEnv {
type CommonEnvironmentVariables = { NODE_ENV: 'development' | 'production' | 'test'
version: string version: string
isCore: boolean
studioPersistenceKey: string
currentProjectStateDefinitionVersion: string
disableStatePersistence?: boolean
} }
// Some environment variables are specific to NODE_ENV='development'
type DevSpecificEnvironmentVariables = {
NODE_ENV: 'development'
devSpecific: {
devServerHost: string
devServerSSL?: {
useSSL?: boolean
pathToKey: string
pathToCert: string
}
}
}
type TestSpecificEnvironmentVariables = {
NODE_ENV: 'test'
}
type ProductionSpecificEnvironmentVariables = {
NODE_ENV: 'production'
}
type EnvironmentVariables =
| (CommonEnvironmentVariables & DevSpecificEnvironmentVariables)
| (CommonEnvironmentVariables & ProductionSpecificEnvironmentVariables)
| (CommonEnvironmentVariables & TestSpecificEnvironmentVariables)
declare let $env: EnvironmentVariables
declare module '*.svg' { declare module '*.svg' {
var s: string var s: string
export default s export default s

View file

@ -1,14 +0,0 @@
{
"NODE_ENV": "development",
"studioPersistenceKey": "theatrejs:0.3/studio",
"currentProjectStateDefinitionVersion": "0.3.0-dev",
"devSpecific": {
"devServerHost": "localhost",
"devServerSSL": {
"useSSL": false,
"pathToKey": "/path/to/cert.key",
"pathToCert": "/path/to/cert.pem"
},
"devServerPort": 10022
}
}

View file

@ -0,0 +1,6 @@
const globals = {
disableStatePersistence: false,
currentProjectStateDefinitionVersion: '0.3.0-dev',
}
export default globals

View file

@ -1,2 +1,3 @@
// @ts-expect-error ignore import globals from './globals'
global.$env = {disableStatePersistence: true, ...process.env, isCore: false}
globals.disableStatePersistence = true

View file

@ -7,12 +7,13 @@ import type {SheetState_Historic} from '@theatre/core/projects/store/types/Sheet
import * as t from '@theatre/shared/propTypes' import * as t from '@theatre/shared/propTypes'
import getStudio from '@theatre/studio/getStudio' import getStudio from '@theatre/studio/getStudio'
import coreTicker from '@theatre/core/coreTicker' import coreTicker from '@theatre/core/coreTicker'
import globals from './globals'
/* eslint-enable no-restricted-syntax */ /* eslint-enable no-restricted-syntax */
let lastProjectN = 0 let lastProjectN = 0
export async function setupTestSheet(sheetState: SheetState_Historic) { export async function setupTestSheet(sheetState: SheetState_Historic) {
const projectState: ProjectState_Historic = { const projectState: ProjectState_Historic = {
definitionVersion: $env.currentProjectStateDefinitionVersion, definitionVersion: globals.currentProjectStateDefinitionVersion,
sheetsById: { sheetsById: {
Sheet: sheetState, Sheet: sheetState,
}, },

View file

@ -12,7 +12,7 @@ export function useForceUpdate(debugLabel?: string) {
const [, setTick] = useState(0) const [, setTick] = useState(0)
const update = useCallback(() => { const update = useCallback(() => {
if ($env.NODE_ENV === 'development' && debugLabel) if (process.env.NODE_ENV !== 'production' && debugLabel)
logger.log(debugLabel, 'forceUpdate', {trace: new Error()}) logger.log(debugLabel, 'forceUpdate', {trace: new Error()})
setTick((tick) => tick + 1) setTick((tick) => tick + 1)

View file

@ -16,9 +16,9 @@ export default function configureStore<State>(conf: Conf<State>): Store<State> {
// const middlewares: $FixMe[] = [] // const middlewares: $FixMe[] = []
const enhancers = [] const enhancers = []
if ($env.NODE_ENV === 'development') { if (process.env.NODE_ENV !== 'production') {
const devtoolsEnhancer: $IntentionalAny = const devtoolsEnhancer: $IntentionalAny =
$env.NODE_ENV === 'development' && process.env.NODE_ENV !== 'production' &&
typeof window === 'object' && typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION__ window.__REDUX_DEVTOOLS_EXTENSION__
? window.__REDUX_DEVTOOLS_EXTENSION__(conf.devtoolsOptions) ? window.__REDUX_DEVTOOLS_EXTENSION__(conf.devtoolsOptions)

View file

@ -26,7 +26,7 @@ export function validateAndSanitiseSlashedPathOrThrow(
fnName: string, fnName: string,
) { ) {
const sanitisedPath = sanifySlashedPath(unsanitisedPath) const sanitisedPath = sanifySlashedPath(unsanitisedPath)
if ($env.isCore) { if (process.env.NODE_ENV !== 'development') {
return sanitisedPath return sanitisedPath
} }
const validation = getValidationErrorsOfSlashedPath(sanitisedPath) const validation = getValidationErrorsOfSlashedPath(sanitisedPath)

View file

@ -32,7 +32,7 @@ export default class Studio {
this.publicApi = new TheatreStudio(this) this.publicApi = new TheatreStudio(this)
this.atomP = this._store.atomP this.atomP = this._store.atomP
if ($env.NODE_ENV !== 'test') { if (process.env.NODE_ENV !== 'test') {
this.ui = new UI(this) this.ui = new UI(this)
} }

View file

@ -26,6 +26,7 @@ import get from 'lodash-es/get'
import type {Store} from 'redux' import type {Store} from 'redux'
import {persistStateOfStudio} from './persistStateOfStudio' import {persistStateOfStudio} from './persistStateOfStudio'
import {isSheetObject} from '@theatre/shared/instanceTypes' import {isSheetObject} from '@theatre/shared/instanceTypes'
import globals from '@theatre/shared/globals'
export type Drafts = { export type Drafts = {
historic: Draft<StudioHistoricState> historic: Draft<StudioHistoricState>
@ -59,7 +60,7 @@ export default class StudioStore {
this._atom = atomFromReduxStore(this._reduxStore) this._atom = atomFromReduxStore(this._reduxStore)
this.atomP = this._atom.pointer this.atomP = this._atom.pointer
if ($env.disableStatePersistence !== true) { if (globals.disableStatePersistence !== true) {
const d = defer<void>() const d = defer<void>()
this.initialized = d.promise this.initialized = d.promise
persistStateOfStudio(this._reduxStore, () => { persistStateOfStudio(this._reduxStore, () => {

View file

@ -5,6 +5,8 @@ import type {FullStudioState} from '@theatre/studio/store/index'
import debounce from 'lodash-es/debounce' import debounce from 'lodash-es/debounce'
import type {Store} from 'redux' import type {Store} from 'redux'
const studioPersistenceKey = 'theatrejs:0.3/studio'
export const persistStateOfStudio = ( export const persistStateOfStudio = (
reduxStore: Store<FullStudioState>, reduxStore: Store<FullStudioState>,
onInitialize: () => void, onInitialize: () => void,
@ -13,7 +15,7 @@ export const persistStateOfStudio = (
reduxStore.dispatch(studioActions.replacePersistentState(s)) reduxStore.dispatch(studioActions.replacePersistentState(s))
} }
const storageKey = $env.studioPersistenceKey + '.persistent' const storageKey = studioPersistenceKey + '.persistent'
const getState = () => reduxStore.getState().$persistent const getState = () => reduxStore.getState().$persistent
loadFromPersistentStorage() loadFromPersistentStorage()

View file

@ -9,7 +9,7 @@ export default class UIRootWrapper extends React.Component<{
componentDidMount() { componentDidMount() {
const self = this const self = this
if ( if (
$env.NODE_ENV === 'development' && process.env.NODE_ENV !== 'production' &&
typeof module === 'object' && typeof module === 'object' &&
module && module &&
module.hot module.hot

View file

@ -11,7 +11,7 @@ const studioPrivateAPI = new Studio()
export const studio = studioPrivateAPI.publicApi export const studio = studioPrivateAPI.publicApi
export default studio export default studio
if ($env.NODE_ENV !== 'test') { if (process.env.NODE_ENV !== 'test') {
studio.ui.show() studio.ui.show()
} }