conjure-js 0.0.12 → 0.0.13
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-cli/conjure-js.mjs +9360 -5298
- package/dist-vite-plugin/index.mjs +9463 -5185
- package/package.json +3 -1
- package/src/bin/cli.ts +2 -2
- package/src/bin/nrepl-symbol.ts +150 -0
- package/src/bin/nrepl.ts +289 -167
- package/src/bin/version.ts +1 -1
- package/src/clojure/core.clj +757 -29
- package/src/clojure/core.clj.d.ts +75 -131
- package/src/clojure/generated/builtin-namespace-registry.ts +4 -0
- package/src/clojure/generated/clojure-core-source.ts +758 -29
- package/src/clojure/generated/clojure-set-source.ts +136 -0
- package/src/clojure/generated/clojure-walk-source.ts +72 -0
- package/src/clojure/set.clj +132 -0
- package/src/clojure/set.clj.d.ts +20 -0
- package/src/clojure/string.clj.d.ts +14 -0
- package/src/clojure/walk.clj +68 -0
- package/src/clojure/walk.clj.d.ts +7 -0
- package/src/core/assertions.ts +114 -6
- package/src/core/bootstrap.ts +337 -0
- package/src/core/conversions.ts +48 -31
- package/src/core/core-module.ts +303 -0
- package/src/core/env.ts +20 -6
- package/src/core/evaluator/apply.ts +40 -25
- package/src/core/evaluator/arity.ts +8 -8
- package/src/core/evaluator/async-evaluator.ts +565 -0
- package/src/core/evaluator/collections.ts +28 -5
- package/src/core/evaluator/destructure.ts +180 -69
- package/src/core/evaluator/dispatch.ts +12 -14
- package/src/core/evaluator/evaluate.ts +22 -20
- package/src/core/evaluator/expand.ts +45 -15
- package/src/core/evaluator/form-parsers.ts +178 -0
- package/src/core/evaluator/index.ts +7 -9
- package/src/core/evaluator/js-interop.ts +189 -0
- package/src/core/evaluator/quasiquote.ts +14 -8
- package/src/core/evaluator/recur-check.ts +6 -6
- package/src/core/evaluator/special-forms.ts +234 -191
- package/src/core/factories.ts +182 -3
- package/src/core/index.ts +54 -4
- package/src/core/module.ts +136 -0
- package/src/core/ns-forms.ts +107 -0
- package/src/core/printer.ts +371 -11
- package/src/core/reader.ts +84 -33
- package/src/core/registry.ts +209 -0
- package/src/core/runtime.ts +376 -0
- package/src/core/session.ts +253 -487
- package/src/core/stdlib/arithmetic.ts +528 -194
- package/src/core/stdlib/async-fns.ts +132 -0
- package/src/core/stdlib/atoms.ts +291 -56
- package/src/core/stdlib/errors.ts +54 -50
- package/src/core/stdlib/hof.ts +82 -166
- package/src/core/stdlib/js-namespace.ts +344 -0
- package/src/core/stdlib/lazy.ts +34 -0
- package/src/core/stdlib/maps-sets.ts +322 -0
- package/src/core/stdlib/meta.ts +61 -30
- package/src/core/stdlib/predicates.ts +325 -187
- package/src/core/stdlib/regex.ts +126 -98
- package/src/core/stdlib/seq.ts +564 -0
- package/src/core/stdlib/strings.ts +164 -135
- package/src/core/stdlib/transducers.ts +95 -100
- package/src/core/stdlib/utils.ts +292 -130
- package/src/core/stdlib/vars.ts +27 -27
- package/src/core/stdlib/vectors.ts +122 -0
- package/src/core/tokenizer.ts +2 -2
- package/src/core/transformations.ts +117 -9
- package/src/core/types.ts +98 -2
- package/src/host/node-host-module.ts +74 -0
- package/src/{vite-plugin-clj/nrepl-relay.ts → nrepl/relay.ts} +72 -11
- package/src/vite-plugin-clj/codegen.ts +87 -95
- package/src/vite-plugin-clj/index.ts +178 -23
- package/src/vite-plugin-clj/namespace-utils.ts +39 -0
- package/src/vite-plugin-clj/static-analysis.ts +211 -0
- package/src/clojure/demo.clj +0 -72
- package/src/clojure/demo.clj.d.ts +0 -0
- package/src/core/core-env.ts +0 -61
- package/src/core/stdlib/collections.ts +0 -739
- package/src/host/node.ts +0 -55
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conjure-js",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.13",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": "./src/core/index.ts",
|
|
15
|
+
"./nrepl": "./src/bin/nrepl.ts",
|
|
15
16
|
"./vite-plugin": {
|
|
16
17
|
"bun": "./src/vite-plugin-clj/index.ts",
|
|
17
18
|
"default": "./dist-vite-plugin/index.mjs"
|
|
@@ -48,6 +49,7 @@
|
|
|
48
49
|
"build-cli": "node scripts/gen-version.mjs && bun build --compile src/bin/cli.ts --outfile conjure-js",
|
|
49
50
|
"build-npm-bin": "node scripts/gen-version.mjs && node scripts/build-npm-bin.mjs",
|
|
50
51
|
"build-vite-plugin": "node scripts/build-vite-plugin.mjs",
|
|
52
|
+
"prepublishOnly": "bun run gen:core-source && node scripts/build-vite-plugin.mjs",
|
|
51
53
|
"typecheck": "tsc --noEmit",
|
|
52
54
|
"test": "vitest",
|
|
53
55
|
"gen:core-source": "bun run scripts/gen-core-source.mjs",
|
package/src/bin/cli.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { extractNsName } from '../vite-plugin-clj/namespace-utils'
|
|
|
12
12
|
import { inferSourceRoot, discoverSourceRoots } from './nrepl-utils'
|
|
13
13
|
import { startNreplServer } from './nrepl'
|
|
14
14
|
import { VERSION } from './version'
|
|
15
|
-
import {
|
|
15
|
+
import { makeNodeHostModule } from '../host/node-host-module'
|
|
16
16
|
|
|
17
17
|
type CliIo = {
|
|
18
18
|
writeLine: (text: string) => void
|
|
@@ -32,7 +32,7 @@ export function createCliSession(sourceRoots: string[], io: CliIo): Session {
|
|
|
32
32
|
sourceRoots,
|
|
33
33
|
readFile: (filePath) => readFileSync(filePath, 'utf8'),
|
|
34
34
|
})
|
|
35
|
-
|
|
35
|
+
session.runtime.installModules([makeNodeHostModule(session)])
|
|
36
36
|
return session
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared symbol resolution and metadata extraction for nREPL ops.
|
|
3
|
+
* Used by both the standalone nREPL server (nrepl.ts) and the browser relay
|
|
4
|
+
* (nrepl-relay.ts) so info/eldoc/lookup work identically in both transports.
|
|
5
|
+
*/
|
|
6
|
+
import { tryLookup, lookupVar, getNamespaceEnv } from '../core/env'
|
|
7
|
+
import { printString } from '../core/printer'
|
|
8
|
+
import type { CljMap, CljValue, CljVar, Session } from '../core'
|
|
9
|
+
|
|
10
|
+
export type ResolvedSymbol = {
|
|
11
|
+
value: CljValue
|
|
12
|
+
resolvedNs: string
|
|
13
|
+
localName: string
|
|
14
|
+
/** The raw CljVar for this symbol, if one exists. Its meta holds :doc/:arglists/:line/:column/:file. */
|
|
15
|
+
varObj?: CljVar
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export type ExtractedMeta = {
|
|
19
|
+
doc: string
|
|
20
|
+
arglistsStr: string
|
|
21
|
+
eldocArgs: string[][] | null
|
|
22
|
+
type: string
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Resolve a symbol string in the context of a session.
|
|
27
|
+
* Handles qualified symbols (ns/name, alias/name) and unqualified symbols.
|
|
28
|
+
* Returns null if the symbol cannot be resolved.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveSymbol(
|
|
31
|
+
sym: string,
|
|
32
|
+
session: Session,
|
|
33
|
+
contextNs?: string
|
|
34
|
+
): ResolvedSymbol | null {
|
|
35
|
+
const ns = contextNs ?? session.currentNs
|
|
36
|
+
const slashIdx = sym.indexOf('/')
|
|
37
|
+
|
|
38
|
+
if (slashIdx > 0) {
|
|
39
|
+
const qualifier = sym.slice(0, slashIdx)
|
|
40
|
+
const localName = sym.slice(slashIdx + 1)
|
|
41
|
+
|
|
42
|
+
// 1. Try as full namespace name
|
|
43
|
+
const nsEnvFull = session.registry.get(qualifier)
|
|
44
|
+
if (nsEnvFull) {
|
|
45
|
+
const value = tryLookup(localName, nsEnvFull)
|
|
46
|
+
if (value !== undefined) {
|
|
47
|
+
const varObj = lookupVar(localName, nsEnvFull)
|
|
48
|
+
return { value, resolvedNs: qualifier, localName, varObj }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// 2. Try as alias (:as str → clojure.string)
|
|
53
|
+
const currentNsData = session.getNs(ns)
|
|
54
|
+
const aliasedNs = currentNsData?.aliases.get(qualifier)
|
|
55
|
+
if (aliasedNs) {
|
|
56
|
+
const varObj = aliasedNs.vars.get(localName)
|
|
57
|
+
if (varObj !== undefined)
|
|
58
|
+
return { value: varObj.value, resolvedNs: aliasedNs.name, localName, varObj }
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Unqualified symbol
|
|
65
|
+
const localName = sym
|
|
66
|
+
const nsEnvFull = session.registry.get(ns)
|
|
67
|
+
if (!nsEnvFull) return null
|
|
68
|
+
const value = tryLookup(sym, nsEnvFull)
|
|
69
|
+
if (value === undefined) return null
|
|
70
|
+
|
|
71
|
+
// Determine the namespace where this symbol is defined.
|
|
72
|
+
const varObj = lookupVar(sym, nsEnvFull)
|
|
73
|
+
let resolvedNs: string
|
|
74
|
+
if (varObj) {
|
|
75
|
+
resolvedNs = varObj.ns
|
|
76
|
+
} else if (value.kind === 'function' || value.kind === 'macro') {
|
|
77
|
+
resolvedNs = getNamespaceEnv(value.env).ns?.name ?? ns
|
|
78
|
+
} else if (value.kind === 'native-function') {
|
|
79
|
+
const i = value.name.indexOf('/')
|
|
80
|
+
resolvedNs = i > 0 ? value.name.slice(0, i) : ns
|
|
81
|
+
} else {
|
|
82
|
+
resolvedNs = ns
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { value, resolvedNs, localName, varObj }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Extract documentation, arglists, and eldoc args from a resolved CljValue.
|
|
90
|
+
* Pass `varMeta` (from the CljVar that holds the value) to get :doc/:arglists
|
|
91
|
+
* stored on the var rather than on the value itself.
|
|
92
|
+
*/
|
|
93
|
+
export function extractMeta(value: CljValue, varMeta?: CljMap): ExtractedMeta {
|
|
94
|
+
const type =
|
|
95
|
+
value.kind === 'macro'
|
|
96
|
+
? 'macro'
|
|
97
|
+
: value.kind === 'function' || value.kind === 'native-function'
|
|
98
|
+
? 'function'
|
|
99
|
+
: 'var'
|
|
100
|
+
|
|
101
|
+
// Prefer var-level metadata (canonical location for :doc/:arglists after the
|
|
102
|
+
// metadata-on-vars refactor). Fall back to value-level meta for backward compat.
|
|
103
|
+
const meta: CljMap | undefined =
|
|
104
|
+
varMeta ??
|
|
105
|
+
(value.kind === 'function'
|
|
106
|
+
? value.meta
|
|
107
|
+
: value.kind === 'native-function'
|
|
108
|
+
? value.meta
|
|
109
|
+
: undefined)
|
|
110
|
+
|
|
111
|
+
let doc = ''
|
|
112
|
+
let arglistsStr = ''
|
|
113
|
+
let eldocArgs: string[][] | null = null
|
|
114
|
+
|
|
115
|
+
if (meta) {
|
|
116
|
+
const docEntry = meta.entries.find(
|
|
117
|
+
([k]) => k.kind === 'keyword' && k.name === ':doc'
|
|
118
|
+
)
|
|
119
|
+
if (docEntry && docEntry[1].kind === 'string') doc = docEntry[1].value
|
|
120
|
+
|
|
121
|
+
const argsEntry = meta.entries.find(
|
|
122
|
+
([k]) => k.kind === 'keyword' && k.name === ':arglists'
|
|
123
|
+
)
|
|
124
|
+
if (argsEntry && argsEntry[1].kind === 'vector') {
|
|
125
|
+
const arglists = argsEntry[1]
|
|
126
|
+
arglistsStr = '(' + arglists.value.map((al) => printString(al)).join(' ') + ')'
|
|
127
|
+
eldocArgs = arglists.value.map((al) => {
|
|
128
|
+
if (al.kind !== 'vector') return [printString(al)]
|
|
129
|
+
return al.value.map((p) => (p.kind === 'symbol' ? p.name : printString(p)))
|
|
130
|
+
})
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Fallback: derive arglists from structural arities (fn/macro without meta)
|
|
135
|
+
if (arglistsStr === '' && (value.kind === 'function' || value.kind === 'macro')) {
|
|
136
|
+
const arityStrs = value.arities.map((arity) => {
|
|
137
|
+
const params = arity.params.map((p) => printString(p))
|
|
138
|
+
if (arity.restParam) params.push('&', printString(arity.restParam))
|
|
139
|
+
return '[' + params.join(' ') + ']'
|
|
140
|
+
})
|
|
141
|
+
arglistsStr = '(' + arityStrs.join(' ') + ')'
|
|
142
|
+
eldocArgs = value.arities.map((arity) => {
|
|
143
|
+
const params = arity.params.map((p) => printString(p))
|
|
144
|
+
if (arity.restParam) params.push('&', printString(arity.restParam))
|
|
145
|
+
return params
|
|
146
|
+
})
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { doc, arglistsStr, eldocArgs, type }
|
|
150
|
+
}
|