@jbrowse/product-core 2.6.1 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './RootModel';
2
2
  export * from './Session';
3
3
  export * from './ui';
4
+ export * from './rpcWorker';
package/dist/index.js CHANGED
@@ -17,3 +17,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./RootModel"), exports);
18
18
  __exportStar(require("./Session"), exports);
19
19
  __exportStar(require("./ui"), exports);
20
+ __exportStar(require("./rpcWorker"), exports);
@@ -0,0 +1,6 @@
1
+ import { LoadedPlugin } from '@jbrowse/core/PluginLoader';
2
+ import { PluginConstructor } from '@jbrowse/core/Plugin';
3
+ export declare function initializeWorker(corePlugins: PluginConstructor[], opts: {
4
+ fetchESM?: (url: string) => Promise<LoadedPlugin>;
5
+ fetchCJS?: (url: string) => Promise<LoadedPlugin>;
6
+ }): Promise<void>;
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.initializeWorker = void 0;
7
+ /* eslint-disable no-restricted-globals */
8
+ const librpc_web_mod_1 = __importDefault(require("librpc-web-mod"));
9
+ const PluginManager_1 = __importDefault(require("@jbrowse/core/PluginManager"));
10
+ const remoteAbortSignals_1 = require("@jbrowse/core/rpc/remoteAbortSignals");
11
+ const PluginLoader_1 = __importDefault(require("@jbrowse/core/PluginLoader"));
12
+ const serialize_error_1 = require("serialize-error");
13
+ // waits for a message from the main thread containing our configuration, which
14
+ // must be sent on boot
15
+ function receiveConfiguration() {
16
+ const configurationP = new Promise(resolve => {
17
+ function listener(e) {
18
+ if (e.data.message === 'config') {
19
+ resolve(e.data.config);
20
+ removeEventListener('message', listener);
21
+ }
22
+ }
23
+ self.addEventListener('message', listener);
24
+ });
25
+ postMessage({ message: 'readyForConfig' });
26
+ return configurationP;
27
+ }
28
+ async function getPluginManager(corePlugins, opts) {
29
+ // Load runtime plugins
30
+ const config = await receiveConfiguration();
31
+ const pluginLoader = new PluginLoader_1.default(config.plugins, opts);
32
+ pluginLoader.installGlobalReExports(self);
33
+ const runtimePlugins = await pluginLoader.load(config.windowHref);
34
+ const plugins = [...corePlugins.map(p => ({ plugin: p })), ...runtimePlugins];
35
+ const pluginManager = new PluginManager_1.default(plugins.map(P => new P.plugin()));
36
+ pluginManager.createPluggableElements();
37
+ pluginManager.configure();
38
+ return pluginManager;
39
+ }
40
+ function wrapForRpc(func) {
41
+ return (args) => {
42
+ const { channel, rpcDriverClassName } = args;
43
+ return func({
44
+ ...args,
45
+ statusCallback: (message) => {
46
+ // @ts-expect-error
47
+ self.rpcServer.emit(channel, message);
48
+ },
49
+ }, rpcDriverClassName);
50
+ };
51
+ }
52
+ async function initializeWorker(corePlugins, opts) {
53
+ try {
54
+ const pluginManager = await getPluginManager(corePlugins, opts);
55
+ const rpcConfig = Object.fromEntries(pluginManager
56
+ .getRpcElements()
57
+ .map(e => [e.name, wrapForRpc(e.execute.bind(e))]));
58
+ // @ts-expect-error
59
+ self.rpcServer = new librpc_web_mod_1.default.Server({
60
+ ...rpcConfig,
61
+ ...(0, remoteAbortSignals_1.remoteAbortRpcHandler)(),
62
+ ping: () => {
63
+ // the ping method is required by the worker driver for checking the
64
+ // health of the worker
65
+ },
66
+ });
67
+ postMessage({ message: 'ready' });
68
+ }
69
+ catch (e) {
70
+ postMessage({ message: 'error', error: (0, serialize_error_1.serializeError)(e) });
71
+ }
72
+ /* do nothing */
73
+ }
74
+ exports.initializeWorker = initializeWorker;
package/esm/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './RootModel';
2
2
  export * from './Session';
3
3
  export * from './ui';
4
+ export * from './rpcWorker';
package/esm/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './RootModel';
2
2
  export * from './Session';
3
3
  export * from './ui';
4
+ export * from './rpcWorker';
@@ -0,0 +1,6 @@
1
+ import { LoadedPlugin } from '@jbrowse/core/PluginLoader';
2
+ import { PluginConstructor } from '@jbrowse/core/Plugin';
3
+ export declare function initializeWorker(corePlugins: PluginConstructor[], opts: {
4
+ fetchESM?: (url: string) => Promise<LoadedPlugin>;
5
+ fetchCJS?: (url: string) => Promise<LoadedPlugin>;
6
+ }): Promise<void>;
@@ -0,0 +1,67 @@
1
+ /* eslint-disable no-restricted-globals */
2
+ import RpcServer from 'librpc-web-mod';
3
+ import PluginManager from '@jbrowse/core/PluginManager';
4
+ import { remoteAbortRpcHandler } from '@jbrowse/core/rpc/remoteAbortSignals';
5
+ import PluginLoader from '@jbrowse/core/PluginLoader';
6
+ import { serializeError } from 'serialize-error';
7
+ // waits for a message from the main thread containing our configuration, which
8
+ // must be sent on boot
9
+ function receiveConfiguration() {
10
+ const configurationP = new Promise(resolve => {
11
+ function listener(e) {
12
+ if (e.data.message === 'config') {
13
+ resolve(e.data.config);
14
+ removeEventListener('message', listener);
15
+ }
16
+ }
17
+ self.addEventListener('message', listener);
18
+ });
19
+ postMessage({ message: 'readyForConfig' });
20
+ return configurationP;
21
+ }
22
+ async function getPluginManager(corePlugins, opts) {
23
+ // Load runtime plugins
24
+ const config = await receiveConfiguration();
25
+ const pluginLoader = new PluginLoader(config.plugins, opts);
26
+ pluginLoader.installGlobalReExports(self);
27
+ const runtimePlugins = await pluginLoader.load(config.windowHref);
28
+ const plugins = [...corePlugins.map(p => ({ plugin: p })), ...runtimePlugins];
29
+ const pluginManager = new PluginManager(plugins.map(P => new P.plugin()));
30
+ pluginManager.createPluggableElements();
31
+ pluginManager.configure();
32
+ return pluginManager;
33
+ }
34
+ function wrapForRpc(func) {
35
+ return (args) => {
36
+ const { channel, rpcDriverClassName } = args;
37
+ return func({
38
+ ...args,
39
+ statusCallback: (message) => {
40
+ // @ts-expect-error
41
+ self.rpcServer.emit(channel, message);
42
+ },
43
+ }, rpcDriverClassName);
44
+ };
45
+ }
46
+ export async function initializeWorker(corePlugins, opts) {
47
+ try {
48
+ const pluginManager = await getPluginManager(corePlugins, opts);
49
+ const rpcConfig = Object.fromEntries(pluginManager
50
+ .getRpcElements()
51
+ .map(e => [e.name, wrapForRpc(e.execute.bind(e))]));
52
+ // @ts-expect-error
53
+ self.rpcServer = new RpcServer.Server({
54
+ ...rpcConfig,
55
+ ...remoteAbortRpcHandler(),
56
+ ping: () => {
57
+ // the ping method is required by the worker driver for checking the
58
+ // health of the worker
59
+ },
60
+ });
61
+ postMessage({ message: 'ready' });
62
+ }
63
+ catch (e) {
64
+ postMessage({ message: 'error', error: serializeError(e) });
65
+ }
66
+ /* do nothing */
67
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jbrowse/product-core",
3
- "version": "2.6.1",
3
+ "version": "2.6.2",
4
4
  "sideEffects": false,
5
5
  "description": "JBrowse 2 code shared between products but not used by plugins",
6
6
  "keywords": [
@@ -27,13 +27,12 @@
27
27
  "module": "esm/index.js",
28
28
  "files": [
29
29
  "dist",
30
- "esm",
31
- "src"
30
+ "esm"
32
31
  ],
33
32
  "scripts": {
34
33
  "build:esm": "tsc --build tsconfig.build.esm.json",
35
- "build:es5": "tsc --build tsconfig.build.es5.json",
36
- "build": "npm run build:esm && npm run build:es5",
34
+ "build:commonjs": "tsc --build tsconfig.build.commonjs.json",
35
+ "build": "npm run build:esm && npm run build:commonjs",
37
36
  "test": "cd ../..; jest packages/product-core",
38
37
  "clean": "rimraf dist esm *.tsbuildinfo",
39
38
  "prebuild": "yarn clean",
@@ -47,7 +46,9 @@
47
46
  "@mui/icons-material": "^5.0.0",
48
47
  "@mui/material": "^5.10.17",
49
48
  "copy-to-clipboard": "^3.3.1",
49
+ "librpc-web-mod": "^1.0.0",
50
50
  "react-error-boundary": "^4.0.3",
51
+ "serialize-error": "^8.0.0",
51
52
  "shortid": "^2.2.15"
52
53
  },
53
54
  "peerDependencies": {
@@ -62,5 +63,5 @@
62
63
  "publishConfig": {
63
64
  "access": "public"
64
65
  },
65
- "gitHead": "1cbe7ba097fb2d2763c776e5e429e4670cdd583c"
66
+ "gitHead": "bbea587a402d9974acdd804a33f4b77f31a2fd5f"
66
67
  }
@@ -1,131 +0,0 @@
1
- import PluginManager from '@jbrowse/core/PluginManager'
2
- import assemblyManagerFactory, {
3
- BaseAssemblyConfigSchema,
4
- } from '@jbrowse/core/assemblyManager'
5
- import RpcManager from '@jbrowse/core/rpc/RpcManager'
6
- import {
7
- IAnyType,
8
- Instance,
9
- SnapshotIn,
10
- cast,
11
- getSnapshot,
12
- isStateTreeNode,
13
- types,
14
- } from 'mobx-state-tree'
15
- import TextSearchManager from '@jbrowse/core/TextSearch/TextSearchManager'
16
-
17
- /**
18
- * #stateModel BaseRootModel
19
- * #category root
20
- * factory function for the Base-level root model shared by all products
21
- */
22
- export function BaseRootModelFactory({
23
- pluginManager,
24
- jbrowseModelType,
25
- sessionModelType,
26
- assemblyConfigSchema,
27
- }: {
28
- pluginManager: PluginManager
29
- jbrowseModelType: IAnyType
30
- sessionModelType: IAnyType
31
- assemblyConfigSchema: BaseAssemblyConfigSchema
32
- }) {
33
- return types
34
- .model('BaseRootModel', {
35
- /**
36
- * #property
37
- * `jbrowse` is a mapping of the config.json into the in-memory state
38
- * tree
39
- */
40
- jbrowse: jbrowseModelType,
41
-
42
- /**
43
- * #property
44
- * `session` encompasses the currently active state of the app, including
45
- * views open, tracks open in those views, etc.
46
- */
47
- session: types.maybe(sessionModelType),
48
- /**
49
- * #property
50
- */
51
- sessionPath: types.optional(types.string, ''),
52
-
53
- /**
54
- * #property
55
- */
56
- assemblyManager: types.optional(
57
- assemblyManagerFactory(assemblyConfigSchema, pluginManager),
58
- {},
59
- ),
60
- })
61
- .volatile(self => ({
62
- rpcManager: new RpcManager(
63
- pluginManager,
64
- self.jbrowse.configuration.rpc,
65
- {
66
- MainThreadRpcDriver: {},
67
- },
68
- ),
69
-
70
- adminMode: false,
71
- isAssemblyEditing: false,
72
- error: undefined as unknown,
73
- textSearchManager: new TextSearchManager(pluginManager),
74
- pluginManager,
75
- }))
76
- .actions(self => ({
77
- /**
78
- * #action
79
- */
80
- setError(error: unknown) {
81
- self.error = error
82
- },
83
- /**
84
- * #action
85
- */
86
- setSession(sessionSnapshot?: SnapshotIn<IAnyType>) {
87
- self.session = cast(sessionSnapshot)
88
- },
89
- /**
90
- * #action
91
- */
92
- setDefaultSession() {
93
- this.setSession(self.jbrowse.defaultSession)
94
- },
95
- /**
96
- * #action
97
- */
98
- setSessionPath(path: string) {
99
- self.sessionPath = path
100
- },
101
- /**
102
- * #action
103
- */
104
- renameCurrentSession(newName: string) {
105
- if (self.session) {
106
- const snapshot = JSON.parse(JSON.stringify(getSnapshot(self.session)))
107
- snapshot.name = newName
108
- this.setSession(snapshot)
109
- }
110
- },
111
- /**
112
- * #action
113
- */
114
- setAssemblyEditing(flag: boolean) {
115
- self.isAssemblyEditing = flag
116
- },
117
- }))
118
- }
119
-
120
- export type BaseRootModelType = ReturnType<typeof BaseRootModelFactory>
121
- export type BaseRootModel = Instance<BaseRootModelType>
122
-
123
- /** Type guard for checking if something is a JB root model */
124
- export function isRootModel(thing: unknown): thing is BaseRootModelType {
125
- return (
126
- isStateTreeNode(thing) &&
127
- 'session' in thing &&
128
- 'jbrowse' in thing &&
129
- 'assemblyManager' in thing
130
- )
131
- }
@@ -1,126 +0,0 @@
1
- import PluginManager from '@jbrowse/core/PluginManager'
2
- import { AnyConfigurationModel } from '@jbrowse/core/configuration'
3
- import { UriLocation } from '@jbrowse/core/util'
4
- import { autorun } from 'mobx'
5
- import { Instance, addDisposer, types } from 'mobx-state-tree'
6
- import { BaseRootModel } from './BaseRootModel'
7
-
8
- /**
9
- * #stateModel InternetAccountsMixin
10
- * #category root
11
- */
12
- export function InternetAccountsRootModelMixin(pluginManager: PluginManager) {
13
- return types
14
- .model({
15
- /**
16
- * #property
17
- */
18
- internetAccounts: types.array(
19
- pluginManager.pluggableMstType('internet account', 'stateModel'),
20
- ),
21
- })
22
- .actions(self => ({
23
- /**
24
- * #action
25
- */
26
- initializeInternetAccount(
27
- internetAccountConfig: AnyConfigurationModel,
28
- initialSnapshot = {},
29
- ) {
30
- const internetAccountType = pluginManager.getInternetAccountType(
31
- internetAccountConfig.type,
32
- )
33
- if (!internetAccountType) {
34
- throw new Error(
35
- `unknown internet account type ${internetAccountConfig.type}`,
36
- )
37
- }
38
-
39
- const length = self.internetAccounts.push({
40
- ...initialSnapshot,
41
- type: internetAccountConfig.type,
42
- configuration: internetAccountConfig,
43
- })
44
- return self.internetAccounts[length - 1]
45
- },
46
-
47
- /**
48
- * #action
49
- */
50
- createEphemeralInternetAccount(
51
- internetAccountId: string,
52
- initialSnapshot = {},
53
- url: string,
54
- ) {
55
- let hostUri
56
-
57
- try {
58
- hostUri = new URL(url).origin
59
- } catch (e) {
60
- // ignore
61
- }
62
- // id of a custom new internaccount is `${type}-${name}`
63
- const internetAccountSplit = internetAccountId.split('-')
64
- const configuration = {
65
- type: internetAccountSplit[0],
66
- internetAccountId: internetAccountId,
67
- name: internetAccountSplit.slice(1).join('-'),
68
- description: '',
69
- domains: hostUri ? [hostUri] : [],
70
- }
71
- const type = pluginManager.getInternetAccountType(configuration.type)
72
- const internetAccount = type.stateModel.create({
73
- ...initialSnapshot,
74
- type: configuration.type,
75
- configuration,
76
- })
77
- self.internetAccounts.push(internetAccount)
78
- return internetAccount
79
- },
80
- /**
81
- * #action
82
- */
83
- findAppropriateInternetAccount(location: UriLocation) {
84
- // find the existing account selected from menu
85
- const selectedId = location.internetAccountId
86
- if (selectedId) {
87
- const selectedAccount = self.internetAccounts.find(account => {
88
- return account.internetAccountId === selectedId
89
- })
90
- if (selectedAccount) {
91
- return selectedAccount
92
- }
93
- }
94
-
95
- // if no existing account or not found, try to find working account
96
- for (const account of self.internetAccounts) {
97
- const handleResult = account.handlesLocation(location)
98
- if (handleResult) {
99
- return account
100
- }
101
- }
102
-
103
- // if still no existing account, create ephemeral config to use
104
- return selectedId
105
- ? this.createEphemeralInternetAccount(selectedId, {}, location.uri)
106
- : null
107
- },
108
- }))
109
- .actions(self => ({
110
- afterCreate() {
111
- addDisposer(
112
- self,
113
- autorun(() => {
114
- const { jbrowse } = self as typeof self & BaseRootModel
115
- jbrowse.internetAccounts.forEach(self.initializeInternetAccount)
116
- }),
117
- )
118
- },
119
- }))
120
- }
121
-
122
- export type RootModelWithInternetAccountsType = ReturnType<
123
- typeof InternetAccountsRootModelMixin
124
- >
125
- export type RootModelWithInternetAccounts =
126
- Instance<RootModelWithInternetAccountsType>
@@ -1,2 +0,0 @@
1
- export * from './BaseRootModel'
2
- export * from './InternetAccounts'
@@ -1,129 +0,0 @@
1
- import shortid from 'shortid'
2
- import PluginManager from '@jbrowse/core/PluginManager'
3
- import {
4
- IAnyStateTreeNode,
5
- Instance,
6
- getParent,
7
- isStateTreeNode,
8
- types,
9
- } from 'mobx-state-tree'
10
- import { AnyConfigurationSchemaType } from '@jbrowse/core/configuration'
11
- import { BaseAssemblyConfigSchema } from '@jbrowse/core/assemblyManager'
12
-
13
- // locals
14
- import type { BaseRootModelType } from '../RootModel/BaseRootModel'
15
-
16
- /**
17
- * #stateModel BaseSessionModel
18
- * base session shared by **all** JBrowse products. Be careful what you include
19
- * here, everything will use it.
20
- */
21
- export function BaseSessionModel<
22
- ROOT_MODEL_TYPE extends BaseRootModelType,
23
- JB_CONFIG_SCHEMA extends AnyConfigurationSchemaType,
24
- >(pluginManager: PluginManager) {
25
- return types
26
- .model({
27
- /**
28
- * #property
29
- */
30
- id: types.optional(types.identifier, shortid()),
31
- /**
32
- * #property
33
- */
34
- name: types.string,
35
- /**
36
- * #property
37
- */
38
- margin: 0,
39
- })
40
- .volatile(() => ({
41
- /**
42
- * #volatile
43
- * this is the globally "selected" object. can be anything. code that
44
- * wants to deal with this should examine it to see what kind of thing it
45
- * is.
46
- */
47
- selection: undefined as unknown,
48
- }))
49
- .views(self => ({
50
- get root() {
51
- return getParent<ROOT_MODEL_TYPE>(self)
52
- },
53
- }))
54
- .views(self => ({
55
- /**
56
- * #getter
57
- */
58
- get jbrowse() {
59
- return self.root.jbrowse
60
- },
61
- /**
62
- * #getter
63
- */
64
- get rpcManager() {
65
- return self.root.rpcManager
66
- },
67
- /**
68
- * #getter
69
- */
70
- get configuration(): Instance<JB_CONFIG_SCHEMA> {
71
- return this.jbrowse.configuration
72
- },
73
- /**
74
- * #getter
75
- */
76
- get adminMode() {
77
- return self.root.adminMode
78
- },
79
-
80
- /**
81
- * #getter
82
- */
83
- get textSearchManager() {
84
- return self.root.textSearchManager
85
- },
86
- }))
87
- .views(self => ({
88
- /**
89
- * #getter
90
- */
91
- get assemblies(): Instance<BaseAssemblyConfigSchema>[] {
92
- return self.jbrowse.assemblies
93
- },
94
- }))
95
- .actions(self => ({
96
- /**
97
- * #action
98
- * set the global selection, i.e. the globally-selected object. can be a
99
- * feature, a view, just about anything
100
- */
101
- setSelection(thing: unknown) {
102
- self.selection = thing
103
- },
104
-
105
- /**
106
- * #action
107
- * clears the global selection
108
- */
109
- clearSelection() {
110
- self.selection = undefined
111
- },
112
- }))
113
- }
114
-
115
- /** Session mixin MST type for the most basic session */
116
- export type BaseSessionType = ReturnType<typeof BaseSessionModel>
117
-
118
- /** Instance of the most basic possible session */
119
- export type BaseSession = Instance<BaseSessionType>
120
-
121
- /** Type guard for BaseSession */
122
- export function isBaseSession(thing: IAnyStateTreeNode): thing is BaseSession {
123
- return 'id' in thing && 'name' in thing && 'root' in thing
124
- }
125
-
126
- /** Type guard for whether a thing is JBrowse session */
127
- export function isSession(thing: unknown): thing is BaseSession {
128
- return isStateTreeNode(thing) && isBaseSession(thing)
129
- }