-
Notifications
You must be signed in to change notification settings - Fork 823
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(flat-services): add flat services
- Loading branch information
Showing
21 changed files
with
871 additions
and
707 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
.loading-page { | ||
position: absolute; | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
width: 100%; | ||
|
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,4 @@ | ||
node_modules/ | ||
dist/ | ||
public/ | ||
*.js |
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,19 @@ | ||
{ | ||
"name": "@netless/flat-services", | ||
"version": "0.1.0", | ||
"description": "Flat Service Manager", | ||
"main": "src/index.ts", | ||
"private": true, | ||
"license": "MIT", | ||
"scripts": { | ||
"build": "tsc" | ||
}, | ||
"dependencies": { | ||
"@netless/flat-rtc": "workspace:*", | ||
"@netless/flat-rtm": "workspace:*" | ||
}, | ||
"devDependencies": { | ||
"prettier": "^2.3.0", | ||
"typescript": "^4.6.2" | ||
} | ||
} |
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,83 @@ | ||
import { FlatRTC } from "@netless/flat-rtc"; | ||
import { FlatRTM } from "@netless/flat-rtm"; | ||
|
||
export interface FlatServicesCatalog { | ||
rtc: FlatRTC; | ||
rtm: FlatRTM; | ||
} | ||
|
||
export type FlatServiceID = Extract<keyof FlatServicesCatalog, string>; | ||
|
||
export type FlatServicesInstance<T extends FlatServiceID> = FlatServicesCatalog[T]; | ||
|
||
export interface FlatServicesPendingCatalog { | ||
rtc: Promise<FlatRTC>; | ||
rtm: Promise<FlatRTM>; | ||
} | ||
|
||
export type FlatServicesCreator<T extends FlatServiceID> = () => Promise<FlatServicesCatalog[T]>; | ||
|
||
export type FlatServicesCreatorCatalog = { | ||
[K in FlatServiceID]: FlatServicesCreator<K>; | ||
}; | ||
|
||
export class FlatServices { | ||
private registry: Partial<FlatServicesCreatorCatalog> = {}; | ||
|
||
private services: Partial<FlatServicesPendingCatalog> = {}; | ||
|
||
public register<T extends FlatServiceID>( | ||
name: T, | ||
serviceCreator: FlatServicesCreatorCatalog[T], | ||
): void { | ||
if (this.isRegistered(name)) { | ||
throw new Error(`${name} is already registered`); | ||
} | ||
this.registry[name] = serviceCreator; | ||
} | ||
|
||
public async unregister<T extends FlatServiceID>(name: T): Promise<boolean> { | ||
if (this.isRegistered(name)) { | ||
this.registry[name] = undefined; | ||
await this.shutdownService(name); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
public async requestService<T extends FlatServiceID>( | ||
name: T, | ||
): Promise<FlatServicesCatalog[T] | undefined> { | ||
if (this.services[name]) { | ||
return this.services[name] as Promise<FlatServicesCatalog[T]>; | ||
} | ||
const creator = this.registry[name]; | ||
if (creator) { | ||
return ((this.services[name] as any) = creator()); | ||
} | ||
return; | ||
} | ||
|
||
public async shutdownService<T extends FlatServiceID = FlatServiceID>( | ||
name: T, | ||
): Promise<boolean> { | ||
const pService: FlatServicesPendingCatalog[FlatServiceID] | undefined = this.services[name]; | ||
if (pService) { | ||
this.services[name] = undefined; | ||
await (await pService).destroy(); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
public isRegistered(name: FlatServiceID): boolean { | ||
return Boolean(this.registry[name]); | ||
} | ||
|
||
public isCreated(name: FlatServiceID): boolean { | ||
return Boolean(this.services[name]); | ||
} | ||
} | ||
|
||
export const flatServices: FlatServices = | ||
(window as any).__FlAtSeRvIcEs || ((window as any).__FlAtSeRvIcEs = new FlatServices()); |
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,12 @@ | ||
{ | ||
"extends": "../../tsconfig.base.json", | ||
"compilerOptions": { | ||
"declaration": true, | ||
"declarationMap": true, | ||
"sourceMap": true, | ||
"composite": true, | ||
"outDir": "./dist", | ||
"rootDir": "./src" | ||
}, | ||
"include": ["./src"] | ||
} |
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 was deleted.
Oops, something went wrong.
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,58 @@ | ||
import React from "react"; | ||
import { createContext } from "react"; | ||
import { | ||
FlatServices, | ||
flatServices, | ||
FlatServiceID, | ||
FlatServicesInstance, | ||
FlatServicesCatalog, | ||
} from "@netless/flat-services"; | ||
import { useIsomorphicLayoutEffect } from "react-use"; | ||
import { useSafePromise } from "flat-components"; | ||
|
||
export const FlatServicesContext = createContext<FlatServices>(flatServices); | ||
|
||
export const FlatServicesContextProvider: React.FC = props => ( | ||
<FlatServicesContext.Provider value={flatServices}> | ||
{props.children} | ||
</FlatServicesContext.Provider> | ||
); | ||
|
||
export const useFlatService = <T extends FlatServiceID>( | ||
name: T, | ||
): FlatServicesInstance<T> | undefined => { | ||
const flatServices = React.useContext(FlatServicesContext); | ||
const [service, setService] = React.useState<FlatServicesInstance<T>>(); | ||
const sp = useSafePromise(); | ||
useIsomorphicLayoutEffect(() => { | ||
sp(flatServices.requestService(name)).then(setService); | ||
}, [flatServices, name]); | ||
return service; | ||
}; | ||
|
||
export type WithFlatServicesProps<P = {}, S extends FlatServiceID = FlatServiceID> = P & | ||
Pick<FlatServicesCatalog, S>; | ||
|
||
export const withFlatServices = <S extends FlatServiceID>(...names: S[]) => { | ||
return <P extends {}>(Component: React.ComponentType<WithFlatServicesProps<P, S>>) => { | ||
const WithFlatServices: React.FC<P> = props => { | ||
const flatServices = React.useContext(FlatServicesContext); | ||
const [services, setServices] = React.useState<Pick<FlatServicesCatalog, S>>(); | ||
const sp = useSafePromise(); | ||
useIsomorphicLayoutEffect(() => { | ||
sp(Promise.all(names.map(name => flatServices.requestService(name)))).then( | ||
serviceList => { | ||
setServices( | ||
serviceList.reduce((acc, service, i) => { | ||
acc[names[i]] = service; | ||
return acc; | ||
}, {} as any), | ||
); | ||
}, | ||
); | ||
}, [flatServices]); | ||
return services ? <Component {...services} {...props} /> : null; | ||
}; | ||
return WithFlatServices; | ||
}; | ||
}; |
Oops, something went wrong.