Skip to content

Commit eaa74c5

Browse files
committed
add local resolver
1 parent ba97505 commit eaa74c5

File tree

24 files changed

+2076
-137
lines changed

24 files changed

+2076
-137
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ To develop the electoron app:
2323
- the repo server is http://localhost:14321/graphql
2424
- When delievered as an electron app, the backend is packaged as a cpkernel pacakge,and the server is launched via electron's main.js process at http://localhost:14321
2525

26+
3. go into ui directory and run `yarn ele` to start the electron app.
27+
2628
To build the electron app:
2729

2830
1. go to ui directory and yarn build. The UI is built into the app.
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// var XXX6 = 8;
2+
3+
// CAUTION this must be var so that it can be evaluted multiple times (during
4+
// debugging)
5+
var CODEPOD_MOD = CODEPOD_MOD || {};
6+
7+
var CODEPOD = {
8+
deleteNames: (ns, names) => {
9+
if (!CODEPOD_MOD[ns]) {
10+
CODEPOD_MOD[ns] = {};
11+
}
12+
for (let name of names) {
13+
eval(`delete CODEPOD_MOD["${ns}"].${name}`);
14+
}
15+
},
16+
addImport: (from, to, name) => {
17+
if (!CODEPOD_MOD[from]) {
18+
CODEPOD_MOD[from] = {};
19+
}
20+
if (!CODEPOD_MOD[to]) {
21+
CODEPOD_MOD[to] = {};
22+
}
23+
// console.log("CODEPOD: addImport", from, to, name);
24+
eval(`CODEPOD_MOD["${to}"].${name} = CODEPOD_MOD["${from}"].${name}`);
25+
return "OK";
26+
},
27+
deleteImport: (ns, name) => {
28+
if (!CODEPOD_MOD[ns]) {
29+
CODEPOD_MOD[ns] = {};
30+
}
31+
eval(`delete CODEPOD_MOD["${ns}"].${name}`);
32+
},
33+
eval: (code, ns, names) => {
34+
// ensure namespace
35+
if (!CODEPOD_MOD[ns]) {
36+
CODEPOD_MOD[ns] = {};
37+
}
38+
// console.log("=== CODEPOD: evaluate in", ns);
39+
// I can start to instantiate names here
40+
for (let k of Object.keys(CODEPOD_MOD[ns])) {
41+
// console.log("=== CODEPOD: bring in", k);
42+
eval(`var ${k} = CODEPOD_MOD["${ns}"].${k}`);
43+
}
44+
// this is a DEF pod
45+
let res = eval(code);
46+
for (let name of names) {
47+
eval(`CODEPOD_MOD["${ns}"].${name} = ${name}`);
48+
}
49+
return res;
50+
},
51+
};
52+
53+
// function CODEPOD3(code, ns, names) {
54+
// // ensure namespace
55+
// if (!CODEPOD_MOD[ns]) {
56+
// CODEPOD_MOD[ns] = {};
57+
// }
58+
// if (names && names.length > 0) {
59+
// // this is a DEF pod
60+
// console.log("CODEPOD: DEF pod");
61+
// let code1 = `
62+
// (() => {
63+
// // already defined names
64+
// for (let k of Object.keys(${ns})) {
65+
// eval("var \${k} = ${ns}.\${k}")
66+
// }
67+
// ${code}
68+
// ${ns} = {...${ns}, ${names.join(",")}}
69+
// })()
70+
// `;
71+
// console.log("CODE: ", code1);
72+
// eval(code1);
73+
// } else {
74+
// console.log("CODEPOD: EVAL pod");
75+
// let code1 = `
76+
// (() => {
77+
// // already defined names
78+
// for (let k of Object.keys(${ns})) {
79+
// eval("var \${k} = ${ns}.\${k}")
80+
// }
81+
// return eval("${code}")
82+
// })()
83+
// `;
84+
// console.log("CODE: ", code1);
85+
// return eval(code1);
86+
// }
87+
// }

cpkernel/kernels/julia/codepod.jl

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
function isModuleDefined(names)
2+
mod = :(Main)
3+
for name in names
4+
name = Symbol(name)
5+
if !isdefined(eval(mod), name)
6+
return false
7+
end
8+
mod = :($mod.$name)
9+
end
10+
return true
11+
end
12+
13+
# function ensureModuleDefined(namespace)
14+
# # ensure the module is defined, and return the module
15+
# # 1. split with /
16+
# names = split(namespace, "/", keepempty=false)
17+
# mod = :(Main)
18+
# for name in names
19+
# name = Symbol(name)
20+
# if !isdefined(eval(mod), name)
21+
# include_string(eval(mod), "module $name using Reexport end")
22+
# end
23+
# mod = :($mod.$name)
24+
# end
25+
# return mod, eval(mod)
26+
# end
27+
28+
29+
function ensureModuleDefined(namespace)
30+
if !isdefined(eval(:Main), Symbol(namespace))
31+
expr = :(module $(Symbol(namespace))
32+
using Reexport
33+
end)
34+
eval(expr)
35+
end
36+
mod = :($(:Main).$(Symbol(namespace)))
37+
return mod, eval(mod)
38+
end
39+
40+
function CODEPOD_EVAL(code, ns)
41+
_, mod = ensureModuleDefined(ns)
42+
include_string(mod, code)
43+
end
44+
45+
46+
function CODEPOD_ADD_IMPORT(from, to, name)
47+
@debug "ensure " from
48+
from_name, _ = ensureModuleDefined(from)
49+
@debug "ensure " to
50+
_, to_mod = ensureModuleDefined(to)
51+
newcode = "using $from_name: $name as CP$name\n$name=CP$name\n$name"
52+
@debug "HEBI: newcode:" newcode
53+
include_string(to_mod, newcode)
54+
end
55+
56+
function CODEPOD_DELETE_IMPORT(ns, name)
57+
_, mod = ensureModuleDefined(ns)
58+
include_string(mod, "$name=nothing")
59+
end
60+
61+
import Pkg
62+
# Pkg.activate("CODEPOD")

cpkernel/kernels/python/codepod.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import ast
2+
import types
3+
4+
5+
def code2parts(code):
6+
ast1 = ast.parse(code)
7+
if not ast1.body:
8+
return [None, None]
9+
if not issubclass(type(ast1.body[-1]), ast.Expr):
10+
return [code, None]
11+
expr = ast.unparse(ast1.body[-1])
12+
if len(ast1.body) == 1:
13+
return [None, expr]
14+
else:
15+
return [ast.unparse(ast1.body[:-1]), expr]
16+
17+
18+
def _make_codepod():
19+
d = {}
20+
21+
def getmod(ns):
22+
if ns not in d:
23+
d[ns] = types.ModuleType(ns)
24+
# for testing purpose
25+
d[ns].__dict__["CODEPOD_GETMOD"] = getmod
26+
return d[ns]
27+
28+
def eval_func(code, ns):
29+
# the codepod(code) is the program sent to backend
30+
# codepod is defined on the kernel
31+
mod = getmod(ns)
32+
[stmt, expr] = code2parts(code)
33+
if stmt:
34+
exec(stmt, mod.__dict__)
35+
if expr:
36+
return eval(expr, mod.__dict__)
37+
38+
return eval_func, getmod
39+
40+
41+
CODEPOD_EVAL, CODEPOD_GETMOD = _make_codepod()
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
(module CODEPOD racket
2+
3+
(require (for-syntax syntax/parse racket rackunit)
4+
racket/enter
5+
rackunit
6+
racket/string
7+
racket/list
8+
racket/port
9+
racket/format
10+
uuid)
11+
12+
(provide
13+
my-ns-enter!
14+
CODEPOD-ADD-IMPORT
15+
CODEPOD-ADD-IMPORT-NS
16+
CODEPOD-DELETE-IMPORT
17+
CODEPOD-EVAL
18+
CODEPOD-link)
19+
20+
;; (enter! #f)
21+
22+
(compile-enforce-module-constants #f)
23+
24+
(define (ns->submod ns)
25+
(let ([names (string-split ns "/")])
26+
(when (not (empty? names))
27+
(let ([one (string->symbol (first names))]
28+
[two (map string->symbol (rest names))])
29+
`(submod ',one
30+
,@two)))))
31+
32+
(define (ns->enter ns)
33+
(let ([mod (ns->submod ns)])
34+
(if (void? mod) '(void)
35+
`(dynamic-enter! ',mod))))
36+
37+
;; (ns->enter "hello/world/aaa")
38+
;; => '(dynamic-enter! '(submod 'hello world aaa))
39+
40+
;; FIXME this will declare new modules every time. Instead, I should go into the module and declare a submodule
41+
(define (ns->ensure-module ns)
42+
(let loop ([names (string-split ns "/")])
43+
(if (empty? names) '(void)
44+
`(module ,(string->symbol (first names)) racket/base
45+
,(loop (rest names))))))
46+
;; (ns->ensure-module "hello/world/aaa")
47+
;; (ns->ensure-module "")
48+
49+
;; FIXME not working, but the expanded code works, weird
50+
(define-syntax (reset-module stx)
51+
(syntax-parse
52+
stx
53+
[(_ ns names ...)
54+
#`(module ns racket
55+
(require rackunit 'CODEPOD)
56+
(provide names ...)
57+
(define names "PLACEHOLDER") ...)]))
58+
59+
(define (my-ns-enter! ns)
60+
(with-handlers
61+
([exn:fail:contract?
62+
(lambda (exn)
63+
(eval
64+
`(module ,(string->symbol ns) racket/base
65+
;; some basic packages
66+
(require rackunit 'CODEPOD)
67+
(void)))
68+
(eval
69+
`(enter! (submod ',(string->symbol ns))))
70+
"OK2")])
71+
(eval
72+
`(enter! (submod ',(string->symbol ns))))
73+
"OK1"))
74+
75+
(define (CODEPOD-ADD-IMPORT from to name)
76+
(let ([name (string->symbol name)])
77+
;; this must not be in a begin form together with (define ...)s
78+
; (eval (ns->enter to))
79+
(my-ns-enter! to)
80+
;; FIXME I cannot require it here, otherwise this file is not loaded
81+
;; (eval (require rackunit))
82+
83+
;; OPTION 1: will not update if the def changes!
84+
; (eval `(define ,name (dynamic-require/expose '',(string->symbol from) ',name)))
85+
;; OPTION 2: will update, but not work on macros
86+
; (eval `(require/expose ',(string->symbol from) (,name)))
87+
;; OPTION 3: seems to work, but only for provided names
88+
;; UDPATE seems not updating either
89+
(eval `(require ',(string->symbol from)))
90+
;; if no return expression, iracket will not send anything back
91+
"OK"))
92+
93+
(define (CODEPOD-ADD-IMPORT-NS to nses)
94+
(my-ns-enter! to)
95+
(for ([ns (string-split nses)])
96+
(eval `(require ',(string->symbol ns))))
97+
"OK")
98+
99+
(define (CODEPOD-DELETE-IMPORT ns name)
100+
; (eval (ns->enter ns))
101+
(my-ns-enter! ns)
102+
(namespace-undefine-variable! (string->symbol name))
103+
"OK")
104+
105+
(define (string->sexp s)
106+
(call-with-input-string
107+
s
108+
(λ (in)
109+
(read in))))
110+
111+
(define (CODEPOD-EVAL code ns)
112+
;; this is required, otherwise ns->ensure-module is not executed correctly
113+
;;
114+
;; I'm removing this because if the #f is not entered, CODEPOD-XXX functions
115+
;; would be undefined. I will call (enter! #f) before CODEPOD-XXX
116+
;;
117+
;; (enter! #f)
118+
; (eval (ns->ensure-module ns))
119+
; (eval (ns->enter ns))
120+
(my-ns-enter! ns)
121+
(begin0
122+
(eval (string->sexp
123+
;; support multiple s-exps in code
124+
(~a "(begin " code ")")))
125+
(enter! #f)))
126+
127+
128+
(define (CODEPOD-link src)
129+
(let-values ([(_ fname __) (split-path src)])
130+
(let* ([id (uuid-string)]
131+
[dir (build-path "/mount/shared/static/" id)]
132+
[dst (build-path dir fname)]
133+
[url (build-path
134+
; "http://api.codepod.test:4000/static/"
135+
id fname)])
136+
(make-directory* dir)
137+
(copy-file src dst)
138+
(~a "CODEPOD-link " (path->string url)))))
139+
140+
)

cpkernel/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"license": "MIT",
1414
"scripts": {
1515
"build": "rm -fr dist/* && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && ./fixup",
16+
"postbuild": "copyfiles kernels/**/* dist/cjs/ && copyfiles kernels/**/* dist/mjs/",
1617
"watch": "watch 'tsc -p tsconfig.json && tsc -p tsconfig-cjs.json' ./src",
1718
"watch2": "watch 'ls' ./src",
1819
"build:watch": "tsc --watch -p tsconfig-cjs.json",
@@ -35,6 +36,7 @@
3536
"zeromq": "^6.0.0-beta.6"
3637
},
3738
"devDependencies": {
39+
"copyfiles": "^2.4.1",
3840
"nodemon": "^2.0.15",
3941
"typescript": "^4.4.4",
4042
"watch": "^1.0.2"

cpkernel/src/exportfs.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import fs from "fs";
66
import * as child from "child_process";
77
import util from "util";
88

9-
import Prisma from "@prisma/client";
10-
const { PrismaClient } = Prisma;
9+
import * as Prisma from "@prisma/client";
10+
// const { PrismaClient } = Prisma;
1111

1212
import fsp from "fs/promises";
1313

14-
const prisma = new PrismaClient();
14+
const prisma = new Prisma.PrismaClient();
1515

1616
const repopath = pathAPI.join(os.homedir(), `.codepod/repos`);
1717

cpkernel/src/index.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
export * from "./socket.js";
2-
export * from "./typedefs.js";
3-
export * from "./resolver.js";
1+
// export * from "./socket.js";
2+
// export * from "./typedefs.js";
3+
// export * from "./resolver.js";
44
export * from "./server.js";
5-
export * from "./exportfs.js";
5+
// export * from "./exportfs.js";

0 commit comments

Comments
 (0)