Skip to content

Commit

Permalink
feat: merge options deeply
Browse files Browse the repository at this point in the history
  • Loading branch information
arianrhodsandlot committed Feb 6, 2024
1 parent 793adb4 commit e660f00
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 25 deletions.
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- update default retroarch-emscripten-build version to v1.17.0
- disable some default inputs in RetroArch
- when some of the passed config items are objects, like `retroarchConfig`, they will be merged with the default items instead of overwriting the default items entirely

### Fixed
- fix export name when using ESM build of retroarch
Expand Down
40 changes: 15 additions & 25 deletions src/nostalgist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {
NostalgistOptionsPartial,
NostalgistResolveFileFunction,
} from './types/nostalgist-options'
import { merge } from './utils'
import { vendors } from './vendors'

function baseName(url: string) {
Expand All @@ -29,10 +30,9 @@ export class Nostalgist {
private emulator: Emulator | undefined

private constructor(options: NostalgistLaunchOptions) {
const mergedOptions = {
...Nostalgist.globalOptions,
...options,
}
const mergedOptions = {}
merge(mergedOptions, Nostalgist.globalOptions, options)
// @ts-expect-error we cannot infer the final type here
this.options = mergedOptions
}

Expand All @@ -59,10 +59,7 @@ export class Nostalgist {
* ```
*/
static configure(options: NostalgistOptionsPartial) {
Nostalgist.globalOptions = {
...Nostalgist.globalOptions,
...options,
}
merge(Nostalgist.globalOptions, options)
}

/**
Expand Down Expand Up @@ -477,10 +474,8 @@ export class Nostalgist {
}

if (element) {
return {
...defaultAppearanceStyle,
...style,
}
merge(defaultAppearanceStyle, style)
return defaultAppearanceStyle
}

const defaultLayoutStyle: Partial<CSSStyleDeclaration> = {
Expand All @@ -491,11 +486,8 @@ export class Nostalgist {
height: '100%',
zIndex: '1',
}
return {
...defaultLayoutStyle,
...defaultAppearanceStyle,
...style,
}
merge(defaultLayoutStyle, defaultAppearanceStyle, style)
return defaultLayoutStyle
}

private async getCoreOption() {
Expand Down Expand Up @@ -610,17 +602,15 @@ export class Nostalgist {
}

private getRetroarchOption() {
return {
...Nostalgist.globalOptions.retroarchConfig,
...this.options.retroarchConfig,
}
const options = {}
merge(options, Nostalgist.globalOptions.retroarchConfig, this.options.retroarchConfig)
return options as typeof this.options.retroarchConfig
}

private getRetroarchCoreOption() {
return {
...Nostalgist.globalOptions.retroarchCoreConfig,
...this.options.retroarchCoreConfig,
}
const options = {}
merge(options, Nostalgist.globalOptions.retroarchCoreConfig, this.options.retroarchCoreConfig)
return options
}

private loadEmulator() {
Expand Down
36 changes: 36 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,39 @@ export async function importCoreJsAsESM({ name, js }: { name: string; js: string
URL.revokeObjectURL(jsBlobUrl)
}
}

function isNil(obj: unknown) {
return obj === undefined || obj === null
}

function isPrimitive(obj: unknown) {
if (isNil(obj)) {
return true
}
const type = typeof obj
const primitevTypes = ['string', 'number', 'boolean', 'bigint', 'symbol', 'function']
return primitevTypes.includes(type)
}

function mergeSourceToTarget(target: any, source: any) {
for (const key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
const targetValue = target[key]
const sourceValue = source[key]
if (isPrimitive(sourceValue)) {
target[key] = sourceValue
} else if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
target[key] = [...targetValue, ...sourceValue]
} else {
target[key] = isPrimitive(targetValue) ? {} : target[key]
merge(target[key], sourceValue)
}
}
}
}

export function merge(target: any, ...sources: any[]) {
for (const source of sources) {
mergeSourceToTarget(target, source)
}
}
25 changes: 25 additions & 0 deletions tests/integration/nostalgist.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,29 @@ describe('nostalgist', () => {
expect(file.fileContent.size).toBeGreaterThan(0)
}
})

test.only('Nostalgist.launch with nested options', async () => {
Nostalgist.configure({
retroarchConfig: {
input_audio_mute: 'a',
input_menu_toggle: 'nul',
},
})

const nostalgist = await Nostalgist.launch({
core: 'fceumm',
rom: 'flappybird.nes',
retroarchConfig: {
input_max_users: 4,
input_audio_mute: 'b',
},
})

const options = nostalgist.getOptions()
expect(options.retroarchConfig).toMatchObject({
menu_driver: 'rgui',
input_menu_toggle: 'nul',
input_audio_mute: 'b',
})
})
})

0 comments on commit e660f00

Please sign in to comment.