-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Embed: IPC (ready signaling, navigation), overrides, docs (#2314)
* Embed: IPC (ready signaling, navigation), overrides * embed docs * TSify utils/parseSearch
- Loading branch information
Showing
15 changed files
with
723 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
import template from 'lodash/template' | ||
import * as R from 'ramda' | ||
import * as React from 'react' | ||
|
||
// XXX: consider using io-ts | ||
interface S3ObjectLinkOverride { | ||
title?: React.ReactNode | ||
href?: (ctx: { | ||
url: string | ||
s3HttpsUri: string | ||
bucket: string | ||
// TODO: add encoded key? | ||
key: string | ||
version: string | ||
}) => string | ||
notification?: React.ReactNode | ||
emit?: 'notify' | 'override' | ||
} | ||
|
||
interface Overrides { | ||
s3ObjectLink?: S3ObjectLinkOverride | ||
} | ||
|
||
export const Context = React.createContext<Overrides>({}) | ||
Context.displayName = 'Overrides' | ||
|
||
export const { Provider } = Context | ||
|
||
function merge<L extends any, R extends any>(l: L, r: R) { | ||
return l ?? r | ||
} | ||
|
||
export function useOverrides(defaults?: Overrides): Overrides { | ||
const overrides = React.useContext(Context) | ||
return React.useMemo( | ||
() => compile(R.mergeDeepWith(merge, overrides, defaults || {})), | ||
[defaults, overrides], | ||
) | ||
} | ||
|
||
export { useOverrides as use } | ||
|
||
function assertIsObject(scope: string, obj: unknown): asserts obj is object { | ||
if (obj != null && typeof obj !== 'object') { | ||
throw new Error(`${scope} must be an object if present`) | ||
} | ||
} | ||
|
||
const compileTemplate = (scope?: string) => (str?: unknown) => { | ||
try { | ||
return typeof str === 'string' | ||
? template(str) | ||
: (str as NonNullable<Overrides['s3ObjectLink']>['href']) | ||
} catch (e) { | ||
if (scope) { | ||
throw new Error(`${scope} must be a valid template string: ${e.message}`) | ||
} | ||
throw e | ||
} | ||
} | ||
|
||
function validateEmit(v: unknown) { | ||
if (!v) return undefined | ||
if (v !== 'notify' && v !== 'override') { | ||
throw new Error( | ||
'.overrides.s3ObjectLink.emit must be either "notify" or "override" or some falsy value', | ||
) | ||
} | ||
return v | ||
} | ||
|
||
const compile = R.evolve({ | ||
s3ObjectLink: { href: compileTemplate(), emit: validateEmit }, | ||
}) | ||
|
||
export function validate(input: unknown) { | ||
assertIsObject('.overrides', input) | ||
assertIsObject('.overrides.s3ObjectLink', (input as any)?.s3ObjectLink) | ||
R.evolve({ | ||
s3ObjectLink: { | ||
href: compileTemplate('.overrides.s3ObjectLink.href'), | ||
emit: validateEmit, | ||
}, | ||
})(input) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.