agnostics 0.0.2 → 0.0.4

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.
@@ -0,0 +1,41 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // BASE //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { CreateLogger } from 'agnostics/logger'
10
+ const { ERR } = CreateLogger( import.meta.url )
11
+
12
+ export class BaseOnCall {
13
+
14
+ className = 'Base'
15
+
16
+ $listenerCbs = {}
17
+
18
+ constructor() {}
19
+
20
+ $call( name, res ) {
21
+ const alls = ['all', '*']
22
+ const includesKey = Object.keys(this.$listenerCbs).includes(name)
23
+ if (!includesKey) return ERR(`NONEXISTENT:`, name)
24
+ for (const callback of this.$listenerCbs[name]) callback(res)
25
+ for (const all of alls) {
26
+ if (this.$listenerCbs[all]) {
27
+ for (const callback of this.$listenerCbs[all]) callback(name, res)
28
+ }
29
+ }
30
+
31
+ }
32
+
33
+ on( name, callback ) {
34
+ const isAll = name === 'all' || name === '*'
35
+ const includesKey = Object.keys(this.$listenerCbs).includes(name)
36
+ if (!includesKey && !isAll) return ERR(`NONEXISTENT:`, name)
37
+ if (!this.$listenerCbs[name]) this.$listenerCbs[name] = []
38
+ this.$listenerCbs[name].push(callback)
39
+ }
40
+
41
+ }
@@ -0,0 +1,33 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // BASE PROMPT //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { CreateLogger } from 'agnostics/logger'
10
+ const { SAY, HMM, ERR, YAY } = CreateLogger( import.meta.url )
11
+
12
+ import { BaseOnCall } from './_BaseOnCall.js'
13
+
14
+ export class BasePrompt extends BaseOnCall {
15
+
16
+ className = 'BasePrompt:BaseOnCall'
17
+
18
+ constructor( ) {
19
+ super()
20
+ }
21
+
22
+ ask( config = { message: '', schema: {} } ) {
23
+
24
+ HMM('ASK NOT IMPLEMENTED:', this.className)
25
+ const { message, schema } = config
26
+ return new Promise( resolve => {
27
+ const res = {}
28
+ for (const [key,value] of Object.entries(schema)) res[key] = true
29
+ resolve(res)
30
+ })
31
+ }
32
+ }
33
+
@@ -0,0 +1,118 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // BASE REMOTE //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ /*
10
+
11
+ CLASSES MUST HAVE:
12
+
13
+ 1) single config on constructor
14
+ 2) some way to post / receive
15
+ 3)
16
+
17
+
18
+ */
19
+
20
+ import { CreateLogger } from 'agnostics/logger'
21
+ const { SAY, ERR, YAY, HMM, HUH } = CreateLogger( import.meta.url )
22
+
23
+ import { BaseOnCall } from './_BaseOnCall.js'
24
+
25
+ export class BaseRemote extends BaseOnCall {
26
+
27
+ className = 'BaseRemote:BaseOnCall'
28
+
29
+ $methodReqs = {
30
+ }
31
+
32
+ constructor() {
33
+ super()
34
+ this.isIniting = true
35
+ }
36
+
37
+ construct() {}
38
+
39
+ getMethodListenerNames() {
40
+ let methodNames = new Set()
41
+ let current = this
42
+ const exclude = ['getMethodListenerNames', 'construct', 'on']
43
+
44
+ do {
45
+ Object.getOwnPropertyNames(current).forEach(prop => {
46
+ if (prop === 'constructor') return
47
+ const desc = Object.getOwnPropertyDescriptor(current, prop)
48
+ if (!desc || prop[0] === '$' || exclude.includes(prop)) return
49
+ if (
50
+ typeof desc.value === 'function' ||
51
+ typeof desc.get === 'function' ||
52
+ typeof desc.set === 'function'
53
+ ) {
54
+ methodNames.add(prop)
55
+ }
56
+ })
57
+
58
+ current = Object.getPrototypeOf(current)
59
+ } while (current !== null && current !== Object.prototype)
60
+
61
+ methodNames = [...methodNames].sort()
62
+ const listenerNames = Object.keys(this.$listenerCbs || {})
63
+ return { methodNames, listenerNames }
64
+ }
65
+
66
+ $initMethodsAndListeners( methodNames, listenerNames ) {
67
+
68
+ // ========= METHODS =========
69
+
70
+ for (const name of methodNames) {
71
+ this.$methodReqs[name] = []
72
+
73
+ this[name] = (...req) => {
74
+
75
+ const type = 'method'
76
+ const index = this.$methodReqs[name].length
77
+ this.$sendRequest( type, name, req, index )
78
+ return new Promise( resolve => {
79
+ this.$methodReqs[name].push( resolve )
80
+ })
81
+ }
82
+ }
83
+
84
+ // ========= CALLBACKS =========
85
+
86
+ for (const listenerCb of listenerNames) {
87
+ this.$listenerCbs[listenerCb] = []
88
+ }
89
+
90
+ // ========= READY =========
91
+
92
+ YAY('REMOTE:', this.className)
93
+
94
+ HUH('➔ METHODS:', methodNames.join(' '))
95
+ HUH('➔ LISTENERS:', listenerNames.join(' '))
96
+ this.isIniting = false
97
+ }
98
+
99
+ $handleResponse( type, index, name, res ) {
100
+
101
+ if (type === 'method') {
102
+ const resolver = this.$methodReqs[name]?.[index]
103
+ if (!resolver) {
104
+ ERR(`REMOTE NO RESOLVER:`, name, index)
105
+ } else {
106
+ this.$methodReqs[name][index](res)
107
+ this.$methodReqs[name][index] = null
108
+ const allDone = this.$methodReqs[name].every(item => item === null)
109
+ if (allDone) this.$methodReqs[name] = []
110
+ }
111
+ } else if (type === 'listener') {
112
+ this.$call( name, res )
113
+ } else {
114
+ HMM(`UNKNOWN RESPONSE:`, {type,name})
115
+ }
116
+ }
117
+
118
+ }
@@ -0,0 +1,12 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // BASES //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+
10
+ export * from './_BaseOnCall.js'
11
+ export * from './_BasePrompt.js'
12
+ export * from './_BaseRemote.js'
@@ -10,45 +10,17 @@ import { Obj, isArr, isNum, isBool } from '../inputs/index.js'
10
10
  import { NormaliseAccept } from './_Parsers.js'
11
11
 
12
12
  import { CreateLogger } from '../logger/index.js'
13
+ import path from 'path'
13
14
  const { SAY, ERR, HMM, HUH } = CreateLogger( import.meta.url )
14
15
 
15
16
 
16
- async function LoadYargs() {
17
-
18
- if (!globalThis.yargsLib || !globalThis.yargsHideBin) {
19
- try {
20
- globalThis.yargsLib = (await import ('yargs')).default
21
- globalThis.yargsHideBin = (await import ('yargs/helpers')).hideBin
22
- return true
23
- } catch(err) {
24
- return ERR(`YARGS UNAVAILABLE`, err)
25
- }
26
- }
27
- }
28
-
29
- async function LoadGlobby() {
30
-
31
- if (!globalThis.globbyLib || !globalThis.pathExtname) {
32
- try {
33
- globalThis.globbyLib = (await import ('globby')).globby
34
- globalThis.pathExtname = (await import ('path')).extname
35
- return true
36
- } catch(err) {
37
- return ERR(`GLOBS UNAVAILABLE`, err)
38
- }
39
- }
40
- }
41
17
 
42
18
  async function GetYargsFiles( value, extensions ) {
43
19
 
44
20
  try {
45
-
46
- if (!(await LoadGlobby())) return []
47
-
48
-
49
21
  const anything = (extensions.length === 0 || extensions.includes('*'))
50
22
 
51
- const found = await globalThis.globbyLib(value, {
23
+ const found = await globalThis.Yargs(value, {
52
24
  onlyFiles: true,
53
25
  expandDirectories: false,
54
26
  caseSensitiveMatch: false
@@ -56,7 +28,7 @@ async function GetYargsFiles( value, extensions ) {
56
28
 
57
29
  const exts = extensions.map( ext => ext.toLowerCase().replaceAll('.',''))
58
30
  const files = anything ? found : found.filter(file => {
59
- const ext = globalThis.pathExtname(file).replaceAll('.','')
31
+ const ext = path.extname(file).replaceAll('.','')
60
32
  return exts.includes(ext)
61
33
  })
62
34
 
@@ -111,14 +83,17 @@ export function ConvertYargsProperty( def, override = {} ) {
111
83
 
112
84
  const array = def.gui == 'files' || isArr(def.type)
113
85
 
114
- return Object.assign({
86
+ const yargsDef = Object.assign({
115
87
  array,
116
88
  describe: def.description,
117
89
  type: GetYargsType(def.type),
118
- coerce: def.oncheck,
90
+ coerce: def.onsend,
119
91
  default: def.default,
120
- accept: NormaliseAccept( def.accept )
92
+ accept: NormaliseAccept( def.accept ),
93
+ choices: def.enum
121
94
  }, override)
95
+
96
+ return yargsDef
122
97
  }
123
98
 
124
99
 
@@ -136,7 +111,7 @@ export function YargsProcessWorkaround() {
136
111
 
137
112
  export class YargsCommand {
138
113
 
139
- command = '$0'
114
+ command = null
140
115
  description = 'N/A'
141
116
  version = 'N/A'
142
117
  positionals = {}
@@ -148,7 +123,6 @@ export class YargsCommand {
148
123
 
149
124
  constructor( { positionals, options = {}, description = 'N/A', version = 'N/A' } ) {
150
125
 
151
-
152
126
  this.description = description
153
127
  this.version = version
154
128
 
@@ -189,15 +163,12 @@ export class YargsCommand {
189
163
 
190
164
  async run( runCallback = async yargsData => {} ) {
191
165
 
192
- if (!(await LoadYargs())) return
193
166
 
194
- YargsProcessWorkaround()
195
-
196
- const args = globalThis.yargsHideBin( process.argv )
197
- const instance = globalThis.yargsLib( args )
167
+ const args = globalThis.YargsBin( process.argv )
168
+ const instance = globalThis.Yargs( args )
198
169
 
199
170
  instance.command(
200
- this.command,
171
+ '$0 '+ this.command + ' [run]', // hack
201
172
  this.description,
202
173
  yargsData => {
203
174
  const positionals = Object.entries(this.positionals)
@@ -270,13 +241,8 @@ export class YargsCLI {
270
241
 
271
242
  async run( runCallback = async (cmdKey, yargsData) => {} ) {
272
243
 
273
- if (!(await LoadYargs())) return
274
-
275
- // YargsProcessWorkaround()
276
-
277
-
278
- const args = globalThis.yargsHideBin( process.argv )
279
- const instance = globalThis.yargsLib( args )
244
+ const args = globalThis.YargsBin( process.argv )
245
+ const instance = globalThis.Yargs( args )
280
246
 
281
247
  for (const [cmdKey, cmdObj] of Object.entries(this.$commands)) {
282
248
 
package/lib/index.js CHANGED
@@ -6,6 +6,9 @@
6
6
  // //
7
7
  //////////////////////////////////////////
8
8
 
9
+ import { fileURLToPath } from 'node:url'
10
+ import { dirname } from 'node:path'
11
+
9
12
  export * from './helpers/index.js'
10
13
  export * from './inputs/index.js'
11
14
  export * from './specification/index.js'
@@ -0,0 +1,62 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // LOADERS //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { CreateLogger } from 'agnostics/logger'
10
+ const { YAY, ERR, SAY } = CreateLogger( import.meta.url )
11
+
12
+ import path from 'path'
13
+ import fs from 'fs/promises'
14
+ import { pathToFileURL } from 'node:url'
15
+
16
+ export async function LoadDep( name, url ) {
17
+
18
+ const [ base, stem ] = url.split('.')
19
+ let mod
20
+
21
+ if (!globalThis[base]) {
22
+ try {
23
+ mod = (await import (base))
24
+ } catch(err) {
25
+ try {
26
+ const pkgDir = path.join(process.cwd(), 'node_modules', base)
27
+ const pkgJsonPath = path.join(pkgDir, 'package.json')
28
+ const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath))
29
+ let entry = pkgJson.main || pkgJson.module || 'index.js'
30
+ if (pkgJson.exports && pkgJson.exports['.']) {
31
+ const exportIndex = pkgJson.exports['.']?.index || pkgJson.exports['.']
32
+ entry = exportIndex.replace(/^\.\//, '')
33
+ }
34
+ const fullEntryPath = path.join(pkgDir, entry)
35
+ const entryUrl = pathToFileURL(fullEntryPath).href
36
+ mod = (await import (entryUrl))
37
+ } catch(err) {
38
+ return ERR(`FAIL:`, name, err.message)
39
+ }
40
+ }
41
+ if (stem) mod = mod[stem]
42
+ globalThis[name] = mod
43
+ YAY(`LOADED:`, name)
44
+ return globalThis[name]
45
+ }
46
+ }
47
+
48
+ export async function LoadWebview() {
49
+ return await LoadDep('Webview', '@webviewjs/webview.Application')
50
+ }
51
+
52
+ export async function LoadYargs() {
53
+
54
+ const YargsLib = await LoadDep('Yargs', 'yargs.default')
55
+ const YargsBin = await LoadDep('YargsBin', 'yargs/helpers.hideBin')
56
+
57
+ return { YargsLib, YargsBin }
58
+ }
59
+
60
+ export async function LoadGlobby() {
61
+ return await LoadDep('Globby', 'globby.globby')
62
+ }
@@ -0,0 +1,9 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // LOADERS //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ export * from './_Loaders.js'
@@ -8,6 +8,21 @@
8
8
 
9
9
  export const Properties = {
10
10
 
11
+ // --------- EVENTS ---------
12
+
13
+ onsend: {
14
+ description: 'callback for checking value before sending',
15
+ matches: [ 'oncheck', 'validate', 'coerce', 'check']
16
+ },
17
+ onreceive: {
18
+ description: 'callback for checking value when received',
19
+ matches: [ 'onreceive', 'validate', 'coerce', 'check']
20
+ },
21
+ onupdate: {
22
+ description: 'callback for updated value',
23
+ matches: [ 'onupdate', 'update', 'change', 'onchange']
24
+ },
25
+
11
26
  // --------- DEFINITION ---------
12
27
 
13
28
  type: {
@@ -68,14 +83,6 @@ export const Properties = {
68
83
  description: 'property can only be read',
69
84
  matches: ['readonly', 'ro']
70
85
  },
71
- oncheck: {
72
- description: 'callback for checking value',
73
- matches: [ 'oncheck', 'validate', 'coerce', 'check']
74
- },
75
- onupdate: {
76
- description: 'callback for updated value',
77
- matches: [ 'onupdate', 'update', 'change', 'onchange']
78
- },
79
86
 
80
87
  // --------- STRUCTURAL ---------
81
88
 
@@ -0,0 +1,15 @@
1
+
2
+
3
+ // @inquirer/prompts
4
+
5
+ async function LoadInquirer() {
6
+
7
+ if (!globalThis.inquirerLib) {
8
+ try {
9
+ globalThis.inquirerLib = (await import ('inquirer')).inquirer
10
+ return true
11
+ } catch(err) {
12
+ return ERR(`GLOBS UNAVAILABLE`, err)
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,182 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // WINDOW TARGET //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { CreateLogger } from 'agnostics/logger'
10
+ const { SAY, ERR, YAY, HUH, HMM } = CreateLogger( import.meta.url )
11
+ import fs from 'node:fs'
12
+
13
+ import { BaseRemote } from '../bases/_BaseRemote.js'
14
+
15
+ export const WebviewConfig = {
16
+
17
+ app: {
18
+ controlFlow: 0, // Poll | WaitUntil | Exit | ExitWithCode
19
+ waitTime: 0, // ms for WaitUntil
20
+ exitCode: 0, // for ExitWithCode
21
+ },
22
+ browser: {
23
+ resizable: true,
24
+ title: 'Hello World',
25
+ width: 800,
26
+ height: 600,
27
+ x: null,
28
+ y: null,
29
+ contentProtection: false,
30
+ alwaysOnTop: false,
31
+ alwaysOnBottom: false,
32
+ visible: true,
33
+ decorations: true, // false = borderless/frameless
34
+ transparent: false, // needs CSS background: transparent
35
+ visibleOnAllWorkspaces: false,
36
+ maximized: false,
37
+ maximizable: true,
38
+ minimizable: true,
39
+ focused: true,
40
+ fullscreen: null // Exclusive | Borderless | null
41
+ },
42
+ webview: {
43
+ enableDevtools: true,
44
+ incognito: false,
45
+ userAgent: null,
46
+ child: false,
47
+ preload: null,
48
+ hotkeysZoom: false,
49
+ theme: 2, // Light | Dark | System
50
+ clipboard: false,
51
+ autoplay: false,
52
+ backForwardNavigationGestures: false
53
+ },
54
+ showDevTools: false
55
+ }
56
+
57
+ const PreloadScript = `
58
+
59
+ console.log('[PRELOAD] safe ipc')
60
+
61
+ globalThis.gt = globalThis
62
+
63
+ gt.postMessage = gt.webkit.messageHandlers.ipc.postMessage || gt.ipc.postMessage || gt.chrome.webview.postMessage
64
+
65
+ `
66
+
67
+
68
+ export class WebviewTarget extends BaseRemote {
69
+
70
+ className = 'WebviewTarget:BaseRemote:BaseOnCall'
71
+
72
+ $instance = null
73
+
74
+ constructor( source, config = {} ) {
75
+
76
+ super()
77
+
78
+ if (!source) throw Error('NO SOURCE')
79
+
80
+ config = { ...WebviewConfig, ...(config || {})}
81
+
82
+ const clean = obj => Object.fromEntries(
83
+ Object.entries(obj).filter(([, v]) => v != null))
84
+
85
+ const isUrl = source.startsWith('http') || source.startsWith('www')
86
+ const isPath = source.startsWith('/')||source.startsWith('.')
87
+ const isHtml = source.trim().startsWith('<')
88
+
89
+ if (isUrl) {
90
+ config.webview.url = source
91
+ } else if (isPath && !isHtml) {
92
+ config.webview.html = fs.readFileSync(source, 'utf8')
93
+ SAY('READ HTML:', source)
94
+ } else {
95
+ config.webview.html = source
96
+ }
97
+
98
+ const appOpts = clean({...WebviewConfig.app, ...config.app})
99
+ const browserOpts = clean({...WebviewConfig.browser, ...config.browser})
100
+ const webviewOpts = clean({...WebviewConfig.webview, ...config.webview})
101
+
102
+ webviewOpts.preload = PreloadScript
103
+
104
+
105
+ const app = new globalThis.Webview( appOpts )
106
+ const browser = app.createBrowserWindow( browserOpts )
107
+ const webview = browser.createWebview( webviewOpts )
108
+
109
+ if (config.showDevTools && !webview.isDevtoolsOpen()) webview.openDevtools()
110
+ if (!config.showDevTools && webview.isDevtoolsOpen()) webview.closeDevtools()
111
+
112
+ app.onEvent(event => {
113
+
114
+ if (event === 0) {
115
+ SAY('WINDOW CLOSE REQ:', event)
116
+ this.$call('closing', 0)
117
+ browser.close()
118
+ } else if (event === 1) {
119
+ SAY('APP CLOSE REQ:', event)
120
+ this.$call('closing', 1)
121
+ app.close()
122
+ } else {
123
+ SAY('MISC EVENT:', event)
124
+ }
125
+ })
126
+
127
+ webview.onIpcMessage( message => {
128
+ SAY('WEBVIEW MESSAGE:', message)
129
+ })
130
+
131
+ this.$instance = { app, browser, webview }
132
+
133
+ }
134
+
135
+ construct( ...constructArguments ) {
136
+
137
+ const { app, browser, webview } = this.$instance
138
+
139
+ const args = constructArguments.map( arg => JSON.stringify(arg) ).join(', ')
140
+
141
+ SAY('EVAL')
142
+ webview.evaluateScript(`
143
+
144
+ console.log('EVAL')
145
+
146
+ gt.app = new App( ${args} )
147
+
148
+ gt.onIpcMessage = async message => {
149
+
150
+ console.log('NEW MESSAGE', message)
151
+ // const res = await app[name](...req)
152
+
153
+ // parentPort.postMessage({
154
+ // type,
155
+ // name,
156
+ // index,
157
+ // res
158
+ // })
159
+ }
160
+
161
+ app.on('*', (name, res) => {
162
+
163
+ console.log('WOOOO', name, res)
164
+ gt.webkit.messageHandlers.ipc.postMessage('data')
165
+ gt.ipc.postMessage({
166
+ type: 'listener',
167
+ name,
168
+ res
169
+ })
170
+ })
171
+ `)
172
+
173
+ // ========= INIT =========
174
+
175
+ return new Promise( resolve => {
176
+ HMM('INITIIALISE (wait)')
177
+ this.resolveConstruct = resolve
178
+ app.run()
179
+ })
180
+ }
181
+
182
+ }
@@ -0,0 +1,9 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // TARGETS //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ export * from './_WebviewTarget.js'
@@ -0,0 +1,67 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // AUTO INSTANCE //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { workerData, parentPort } from 'worker_threads'
10
+ const { importUrl, importName, constructArguments } = workerData
11
+
12
+ import { CreateLogger } from 'agnostics/logger'
13
+ const { SAY, ERR } = CreateLogger( import.meta.url )
14
+ import path from 'node:path'
15
+
16
+ async function RunInstance() {
17
+
18
+ // ========= INSTANTIATE =========
19
+
20
+ const cwdImportUrl = path.resolve( process.cwd(), importUrl )
21
+ const imported = await import(cwdImportUrl)
22
+ const instantiator = imported[importName]
23
+ if (!instantiator) return ERR('NO INSTANCE:', importUrl, importName)
24
+
25
+ // ========= INSTANCE =========
26
+
27
+ const instance = new instantiator()
28
+ await instance.construct( ...constructArguments )
29
+
30
+ // ========= REQ / RES =========
31
+
32
+ parentPort.on( 'message', async ({type,name,req,index}) => {
33
+
34
+ const res = await instance[name](...req)
35
+
36
+ parentPort.postMessage({
37
+ type,
38
+ name,
39
+ index,
40
+ res
41
+ })
42
+ })
43
+
44
+ // ========= ALL EVENTS =========
45
+
46
+ instance.on('*', (name, res) => {
47
+
48
+ parentPort.postMessage({
49
+ type: 'listener',
50
+ name,
51
+ res
52
+ })
53
+ })
54
+
55
+ // ========= INIT METHODS =========
56
+
57
+ const methodListenerNames = instance.getMethodListenerNames()
58
+
59
+ parentPort.postMessage({
60
+ name: 'methodListenerNames',
61
+ res: methodListenerNames
62
+ })
63
+
64
+
65
+ }
66
+
67
+ RunInstance()
@@ -0,0 +1,136 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // AUTO WORKER //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ import { CreateLogger } from 'agnostics/logger'
10
+ const { SAY, ERR, YAY, HMM, HUH } = CreateLogger( import.meta.url )
11
+
12
+ import { Worker } from 'node:worker_threads'
13
+ import { BaseRemote } from '../bases/_BaseRemote.js'
14
+
15
+ import { fileURLToPath } from 'node:url'
16
+ import path from 'node:path'
17
+
18
+ // Get the directory of the CURRENT file
19
+ const __filename = fileURLToPath(import.meta.url)
20
+ const _dir = path.dirname(__filename)
21
+
22
+ // We use a template literal or a joined string that Rollup
23
+ // can't resolve statically during the build.
24
+ const workerFilename = '_AutoRunner.js';
25
+ export const AutoRunnerPath = path.join(_dir, 'workers', workerFilename);
26
+
27
+ export class AutoWorker extends BaseRemote {
28
+
29
+ className = 'AutoWorker:BaseRemote'
30
+
31
+ $worker = null
32
+
33
+ $listenerCbs = {
34
+ error: [],
35
+ exit: [],
36
+ online: []
37
+ }
38
+
39
+ importUrl = null
40
+ importName = null
41
+
42
+ constructor( importPath ) {
43
+
44
+ super() // Base = on / $call pattern
45
+
46
+ let [ importUrl, importName ] = importPath.split('?')
47
+ if (importName === '') importName = 'default'
48
+
49
+ this.importUrl = importUrl
50
+ this.importName = importName
51
+
52
+ }
53
+
54
+ $sendRequest( type, name, req, index) {
55
+
56
+ this.$worker.postMessage({
57
+ type,
58
+ name,
59
+ req,
60
+ index
61
+ })
62
+ }
63
+
64
+ construct( ...constructArguments ) {
65
+
66
+ const { importUrl, importName } = this
67
+
68
+ this.className = importName + ':' + this.className
69
+
70
+ this.$worker = new Worker(
71
+ new URL('./_AutoRunner.js?worker', import.meta.url).pathname,
72
+ {
73
+ type: 'module',
74
+ workerData: {
75
+ importUrl,
76
+ importName,
77
+ constructArguments
78
+ }})
79
+
80
+ // ========= MESSAGES =========
81
+
82
+ this.$worker.on('message', message => {
83
+
84
+ // ========= INIT =========
85
+
86
+ if (message.name === 'methodListenerNames') {
87
+
88
+ const { methodNames, listenerNames } = message.res
89
+ this.$initMethodsAndListeners( methodNames, listenerNames )
90
+
91
+ } else {
92
+
93
+ // ========= RESPONSE =========
94
+
95
+ const { type, index, name, res } = message
96
+ this.$handleResponse( type, index, name, res )
97
+ }
98
+
99
+ if (this.finishConstruct) {
100
+ HUH('INITED / finishConstruct')
101
+ this.finishConstruct()
102
+ this.finishConstruct = null
103
+ }
104
+ })
105
+
106
+ // ========= ERROR =========
107
+
108
+ this.$worker.on('error', message => {
109
+ ERR('ERROR:', message)
110
+ this.$call( 'error', message )
111
+ })
112
+
113
+ // ========= EXIT =========
114
+
115
+ this.$worker.on('exit', message => {
116
+ HMM('EXIT:', message)
117
+ this.$call( 'exit', message )
118
+ })
119
+
120
+ // ========= ONLINE =========
121
+
122
+ this.$worker.on('online', message => {
123
+ YAY('WORKER ONLINE')
124
+ this.$call( 'online', true )
125
+ })
126
+
127
+ // ========= INIT =========
128
+
129
+ return new Promise( resolve => {
130
+ HMM('INITIIALISE (wait)')
131
+ this.finishConstruct = resolve
132
+ })
133
+ }
134
+
135
+
136
+ }
@@ -0,0 +1,9 @@
1
+ //////////////////////////////////////////
2
+ // //
3
+ // //
4
+ // AUTOWORKER //
5
+ // //
6
+ // //
7
+ //////////////////////////////////////////
8
+
9
+ export * from './_AutoWorker.js'
package/package.json CHANGED
@@ -1,32 +1,32 @@
1
1
  {
2
2
  "name": "agnostics",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "author": "Autr <g@sinnott.cc>",
5
5
  "description": "featherless birds",
6
+ "esversion": 6,
7
+ "type": "module",
6
8
  "exports": {
7
9
  ".": {
8
- "types": "./types/lib/index.d.ts",
10
+ "types": "./types/index.d.ts",
9
11
  "default": "./lib/index.js"
10
12
  },
11
13
  "./inputs": {
12
- "types": "./types/lib/inputs/index.d.ts",
14
+ "types": "./types/inputs/index.d.ts",
13
15
  "default": "./lib/inputs/index.js"
14
16
  },
15
17
  "./helpers": {
16
- "types": "./types/lib/helpers/index.d.ts",
18
+ "types": "./types/helpers/index.d.ts",
17
19
  "default": "./lib/helpers/index.js"
18
20
  },
19
21
  "./specification": {
20
- "types": "./types/lib/specification/index.d.ts",
22
+ "types": "./types/specification/index.d.ts",
21
23
  "default": "./lib/specification/index.js"
22
24
  },
23
25
  "./logger": {
24
- "types": "./types/lib/logger/index.d.ts",
26
+ "types": "./types/logger/index.d.ts",
25
27
  "default": "./lib/logger/index.js"
26
28
  }
27
29
  },
28
30
  "files": [ "lib", "types" ],
29
- "esversion": 6,
30
- "type": "module",
31
31
  "dependencies": {}
32
32
  }