js part compiles
This commit is contained in:
65
Cargo.lock
generated
65
Cargo.lock
generated
@@ -795,6 +795,15 @@ dependencies = [
|
|||||||
"windows-sys 0.61.2",
|
"windows-sys 0.61.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.17",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.27"
|
version = "0.2.27"
|
||||||
@@ -834,6 +843,18 @@ dependencies = [
|
|||||||
"spin",
|
"spin",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flume"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"spin",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
@@ -873,9 +894,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -888,9 +909,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
@@ -898,15 +919,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
@@ -921,9 +942,9 @@ checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -932,21 +953,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.31"
|
version = "0.3.32"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
@@ -956,7 +977,6 @@ dependencies = [
|
|||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
"memchr",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"pin-utils",
|
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1443,7 +1463,10 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"deno_core",
|
"deno_core",
|
||||||
|
"flume 0.12.0",
|
||||||
|
"futures",
|
||||||
"mize",
|
"mize",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1542,7 +1565,7 @@ dependencies = [
|
|||||||
"daemonize",
|
"daemonize",
|
||||||
"dyn-clone",
|
"dyn-clone",
|
||||||
"flate2",
|
"flate2",
|
||||||
"flume",
|
"flume 0.11.1",
|
||||||
"home",
|
"home",
|
||||||
"http_req",
|
"http_req",
|
||||||
"interner",
|
"interner",
|
||||||
@@ -1739,12 +1762,6 @@ version = "0.2.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "pin-utils"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "potential_utf"
|
name = "potential_utf"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
{
|
{
|
||||||
"workspace": ["./packages/ppc/platform/obsidian", "./packages/marts"],
|
"workspace": [
|
||||||
|
"./packages/ppc/platform/obsidian",
|
||||||
|
"./packages/marts",
|
||||||
|
"./packages/mize"
|
||||||
|
],
|
||||||
"imports": {}
|
"imports": {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
|
|
||||||
let expanded = quote! {
|
let expanded = quote! {
|
||||||
#input
|
#input
|
||||||
use std::any::Any;
|
|
||||||
|
|
||||||
// impl the default new impl
|
// impl the default new impl
|
||||||
impl mize::MizePartGenerated for #struct_name {
|
impl mize::MizePartGenerated for #struct_name {
|
||||||
@@ -45,13 +44,13 @@ pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
fn get_mize_generated(&mut self) -> &mut Mize {
|
fn get_mize_generated(&mut self) -> &mut Mize {
|
||||||
&mut self.mize
|
&mut self.mize
|
||||||
}
|
}
|
||||||
fn as_any_generated(&self) -> &dyn Any {
|
fn as_any_generated(&self) -> &dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
fn as_any_mut_generated(&mut self) -> &mut dyn Any {
|
fn as_any_mut_generated(&mut self) -> &mut dyn std::any::Any {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
fn into_any_generated(self: Box<Self>) -> Box<dyn Any> {
|
fn into_any_generated(self: Box<Self>) -> Box<dyn std::any::Any> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,6 +63,22 @@ pub fn mize_part(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
impl std::ops::Deref for mize::MizePartGuard<#struct_name> {
|
||||||
|
type Target = #struct_name;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&*self.part.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::DerefMut for mize::MizePartGuard<#struct_name> {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut *self.part.as_mut().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
TokenStream::from(expanded)
|
TokenStream::from(expanded)
|
||||||
|
|||||||
@@ -7,11 +7,14 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
clap = { version = "4.5.59", optional = true }
|
clap = { version = "4.5.59", optional = true }
|
||||||
deno_core = { version = "0.385.0", optional = true }
|
deno_core = { version = "0.385.0", optional = true }
|
||||||
|
flume = "0.12.0"
|
||||||
|
futures = "0.3.32"
|
||||||
mize = { path = "../mize/", default-features = false }
|
mize = { path = "../mize/", default-features = false }
|
||||||
|
tokio = "1.49.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["target-os"]
|
default = ["target-os"]
|
||||||
target-os = [ "clap", "mize/target-os" ]
|
target-os = [ "clap", "mize/target-os", "deno_core" ]
|
||||||
target-wasm = [ "mize/target-wasm" ]
|
target-wasm = [ "mize/target-wasm" ]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
"name": "@ppc/marts",
|
"name": "@ppc/marts",
|
||||||
"imports": {},
|
"imports": {},
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./index.ts"
|
".": "./index.ts",
|
||||||
|
"stub_deno": "./js/stub_deno.ts"
|
||||||
|
},
|
||||||
|
"tasks": {
|
||||||
|
"build": "deno bundle -o ./deno_dist/habitica.js ./habitica.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
packages/marts/deno_dist/habitica.js
Normal file
75
packages/marts/deno_dist/habitica.js
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
// habitica.ts
|
||||||
|
var opts = {
|
||||||
|
"habitica.api_url": {
|
||||||
|
env_var_name: "PPC_HABITICA_API_URL",
|
||||||
|
default_val: "https://habitica.com/api/v3"
|
||||||
|
},
|
||||||
|
"habitica.user_id": {
|
||||||
|
env_var_name: "PPC_HABITICA_USER_ID"
|
||||||
|
},
|
||||||
|
"habitica.client_name": {
|
||||||
|
default_val: "3544a0b8-d71a-46e0-9bb1-6ddbb2abcddb-PPC-Software"
|
||||||
|
},
|
||||||
|
"habitica.api_token": {
|
||||||
|
env_var_name: "PPC_HABITICA_API_TOKEN"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
async function habitica(mize) {
|
||||||
|
console.log("hiiiiiiiiiiiiiiiiiiii");
|
||||||
|
mize.add_opts(opts);
|
||||||
|
mize.add_part(new Habitica(mize));
|
||||||
|
}
|
||||||
|
async function handleRateLimit(response) {
|
||||||
|
const limit = response.headers.get("X-RateLimit-Limit") || "NONE";
|
||||||
|
const remaining = parseInt(response.headers.get("X-RateLimit-Remaining") || "10", 10);
|
||||||
|
const reset = response.headers.get("X-RateLimit-Reset");
|
||||||
|
console.log(`RateLimit: ${limit} | Remaining: ${remaining} | Reset: ${reset}`);
|
||||||
|
if (remaining < 2 && reset) {
|
||||||
|
const resetDate = new Date(reset);
|
||||||
|
const now = /* @__PURE__ */ new Date();
|
||||||
|
const waitMs = resetDate.getTime() - now.getTime() + 1e3;
|
||||||
|
if (waitMs > 0) {
|
||||||
|
console.log(`Waiting ${Math.round(waitMs / 1e3)} secs for next rate limit window...`);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var Habitica = class {
|
||||||
|
mize;
|
||||||
|
constructor(mize) {
|
||||||
|
this.mize = mize;
|
||||||
|
}
|
||||||
|
async get_tasks(type = "todos") {
|
||||||
|
return await this.api_request("GET", `tasks/user?type=${type}`);
|
||||||
|
}
|
||||||
|
async delete_task(id) {
|
||||||
|
await this.api_request("DELETE", `tasks/${id}`);
|
||||||
|
}
|
||||||
|
async api_request(method, path, extraHeaders = {}, data = {}) {
|
||||||
|
const mize = this.mize;
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
path = "/" + path;
|
||||||
|
}
|
||||||
|
const headers = Object.assign({
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-api-user": mize.get_config("habitica.user_id"),
|
||||||
|
"x-api-key": mize.get_config("habitica.api_token"),
|
||||||
|
"x-client": mize.get_config("habitica.client_name")
|
||||||
|
}, extraHeaders);
|
||||||
|
const response = await fetch(mize.get_config("habitica.api_url") + path, {
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
});
|
||||||
|
await handleRateLimit(response);
|
||||||
|
if (!response.ok) {
|
||||||
|
console.log("request_url:", mize.get_config("habitica.api_url") + path);
|
||||||
|
throw new Error(`Habitica API error: ${response.status} ${response.statusText}`);
|
||||||
|
}
|
||||||
|
return (await response.json()).data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
export {
|
||||||
|
habitica,
|
||||||
|
opts
|
||||||
|
};
|
||||||
105
packages/marts/habitica.ts
Normal file
105
packages/marts/habitica.ts
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
import { Mize } from "@ppc/marts/stub_deno";
|
||||||
|
|
||||||
|
export const opts = {
|
||||||
|
"habitica.api_url": {
|
||||||
|
env_var_name: "PPC_HABITICA_API_URL",
|
||||||
|
default_val: "https://habitica.com/api/v3",
|
||||||
|
},
|
||||||
|
"habitica.user_id": {
|
||||||
|
env_var_name: "PPC_HABITICA_USER_ID",
|
||||||
|
},
|
||||||
|
"habitica.client_name": {
|
||||||
|
default_val: "3544a0b8-d71a-46e0-9bb1-6ddbb2abcddb-PPC-Software",
|
||||||
|
},
|
||||||
|
"habitica.api_token": {
|
||||||
|
env_var_name: "PPC_HABITICA_API_TOKEN",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function habitica(mize: Mize) {
|
||||||
|
console.log("hiiiiiiiiiiiiiiiiiiii");
|
||||||
|
mize.add_opts(opts);
|
||||||
|
|
||||||
|
mize.add_part(new Habitica(mize));
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleRateLimit(response) {
|
||||||
|
const limit = response.headers.get("X-RateLimit-Limit") || "NONE";
|
||||||
|
const remaining = parseInt(
|
||||||
|
response.headers.get("X-RateLimit-Remaining") || "10",
|
||||||
|
10,
|
||||||
|
);
|
||||||
|
const reset = response.headers.get("X-RateLimit-Reset");
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`RateLimit: ${limit} | Remaining: ${remaining} | Reset: ${reset}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (remaining < 2 && reset) {
|
||||||
|
const resetDate = new Date(reset);
|
||||||
|
const now = new Date();
|
||||||
|
const waitMs = resetDate.getTime() - now.getTime() + 1000;
|
||||||
|
|
||||||
|
if (waitMs > 0) {
|
||||||
|
console.log(
|
||||||
|
`Waiting ${Math.round(waitMs / 1000)} secs for next rate limit window...`,
|
||||||
|
);
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Habitica {
|
||||||
|
mize: Mize;
|
||||||
|
|
||||||
|
constructor(mize: Mize) {
|
||||||
|
this.mize = mize;
|
||||||
|
}
|
||||||
|
|
||||||
|
async get_tasks(type: string = "todos") {
|
||||||
|
return await this.api_request("GET", `tasks/user?type=${type}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete_task(id: string) {
|
||||||
|
await this.api_request("DELETE", `tasks/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async api_request(
|
||||||
|
method: string,
|
||||||
|
path: string,
|
||||||
|
extraHeaders: object = {},
|
||||||
|
data: object = {},
|
||||||
|
) {
|
||||||
|
const mize = this.mize;
|
||||||
|
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
path = "/" + path;
|
||||||
|
}
|
||||||
|
const headers = Object.assign(
|
||||||
|
{
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"x-api-user": mize.get_config("habitica.user_id"),
|
||||||
|
"x-api-key": mize.get_config("habitica.api_token"),
|
||||||
|
"x-client": mize.get_config("habitica.client_name"),
|
||||||
|
},
|
||||||
|
extraHeaders,
|
||||||
|
);
|
||||||
|
|
||||||
|
const response = await fetch(mize.get_config("habitica.api_url") + path, {
|
||||||
|
method,
|
||||||
|
headers,
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
});
|
||||||
|
|
||||||
|
await handleRateLimit(response);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
console.log("request_url:", mize.get_config("habitica.api_url") + path);
|
||||||
|
throw new Error(
|
||||||
|
`Habitica API error: ${response.status} ${response.statusText}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (await response.json()).data;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
packages/marts/js/glue_deno.js
Normal file
0
packages/marts/js/glue_deno.js
Normal file
35
packages/marts/js/glue_deno.rs
Normal file
35
packages/marts/js/glue_deno.rs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
use deno_core::extension;
|
||||||
|
use deno_core::op2;
|
||||||
|
use deno_core::OpState;
|
||||||
|
use mize::{Mize, MizeError};
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
fn op_mize_get_part(#[string] name: &str) {
|
||||||
|
println!("js wants the part {}", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2]
|
||||||
|
#[string]
|
||||||
|
fn op_mize_get_config(state: &mut OpState, #[string] key: &str) -> String {
|
||||||
|
let mize: Mize = state.borrow::<Mize>().clone();
|
||||||
|
format!("config_value_for_{}", key)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
fn op_mize_add_part(state: &mut OpState, #[string] key: &str) {
|
||||||
|
let mize: Mize = state.borrow::<Mize>().clone();
|
||||||
|
println!("adding part {}", key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an extension with your custom ops
|
||||||
|
extension!(
|
||||||
|
my_extension,
|
||||||
|
ops = [op_mize_get_part, op_mize_get_config],
|
||||||
|
options = {
|
||||||
|
mize: Mize,
|
||||||
|
},
|
||||||
|
state = |state: &mut OpState, config: Config| {
|
||||||
|
state.put::<Mize>(config.mize);
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -1,32 +1,30 @@
|
|||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::FsModuleLoader;
|
use deno_core::url::Url;
|
||||||
use deno_core::{extension, op2, JsRuntime, ModuleSpecifier, PollEventLoopOptions, RuntimeOptions};
|
use deno_core::{extension, op2, JsRuntime, ModuleSpecifier, PollEventLoopOptions, RuntimeOptions};
|
||||||
|
use deno_core::{FastStaticString, FsModuleLoader};
|
||||||
use mize::async_trait;
|
use mize::async_trait;
|
||||||
use mize::instance::MizePartCreate;
|
use mize::instance::MizePartCreate;
|
||||||
use mize::{mize_part, Mize, MizePart, MizeResult};
|
use mize::{mize_part, Mize, MizePart, MizeResult};
|
||||||
|
use std::future::Future;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::pin::Pin;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use tokio::runtime::Builder;
|
||||||
|
use tokio::task::{spawn_local, LocalSet};
|
||||||
|
|
||||||
|
mod glue_deno;
|
||||||
|
|
||||||
#[mize_part("js")]
|
#[mize_part("js")]
|
||||||
|
#[derive(Default)]
|
||||||
pub struct JsPart {
|
pub struct JsPart {
|
||||||
mize: Mize,
|
mize: Mize,
|
||||||
js_runtime: JsRuntime,
|
closure_sender: Option<flume::Sender<Box<dyn FnOnce(&mut JsRuntime) -> MizeResult<()> + Send>>>,
|
||||||
|
async_closure_sender: Option<flume::Sender<BoxClosure>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define your custom ops for the "mize" object inside deno
|
pub type BoxFuture<'a> = Pin<Box<dyn Future<Output = MizeResult<()>> + 'a>>;
|
||||||
#[op2(fast)]
|
pub type BoxClosure = Box<dyn for<'a> FnOnce(&'a mut JsRuntime) -> BoxFuture<'a> + Send + 'static>;
|
||||||
fn op_mize_get_part(#[string] name: &str) {
|
|
||||||
println!("js wants the part {}", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2]
|
|
||||||
#[string]
|
|
||||||
fn op_mize_get_config(#[string] key: &str) -> String {
|
|
||||||
format!("config_value_for_{}", key)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create an extension with your custom ops
|
|
||||||
extension!(mize_ext, ops = [op_mize_get_part, op_mize_get_config]);
|
|
||||||
|
|
||||||
impl MizePart for JsPart {
|
impl MizePart for JsPart {
|
||||||
fn init(&mut self, mize: &mut Mize) -> MizeResult<()> {
|
fn init(&mut self, mize: &mut Mize) -> MizeResult<()> {
|
||||||
@@ -35,26 +33,44 @@ impl MizePart for JsPart {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn js(mize: &mut Mize) -> Box<dyn MizePart> {
|
pub fn js(mize: &mut Mize) -> MizeResult<()> {
|
||||||
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
let (closure_sender, closure_receiver) =
|
||||||
module_loader: Some(Rc::new(FsModuleLoader)),
|
flume::unbounded::<Box<dyn FnOnce(&mut JsRuntime) -> MizeResult<()> + Send>>();
|
||||||
extensions: vec![mize_ext::init_ops()],
|
let (async_closure_sender, async_closure_receiver) = flume::unbounded::<BoxClosure>();
|
||||||
..Default::default()
|
let mize_clone = mize.clone();
|
||||||
});
|
|
||||||
let bootstrap_code = r#"
|
|
||||||
globalThis.mize = {
|
|
||||||
get_part: (name) => Deno.core.ops.op_mize_get_part(name),
|
|
||||||
get_config: (key) => Deno.core.ops.op_mize_get_config(key),
|
|
||||||
version: "1.0.0",
|
|
||||||
// Add more methods as needed
|
|
||||||
};
|
|
||||||
"#;
|
|
||||||
|
|
||||||
js_runtime.execute_script("[bootstrap]", bootstrap_code)?;
|
// the thread which will run any js
|
||||||
JsPart { mize, js_runtime }
|
mize.spawn("js_runtime_thread", || {
|
||||||
|
js_runtime_thread(mize_clone, closure_receiver, async_closure_receiver)
|
||||||
|
})?;
|
||||||
|
|
||||||
|
mize.add_part(Box::new(JsPart {
|
||||||
|
mize: mize.clone(),
|
||||||
|
closure_sender: Some(closure_sender),
|
||||||
|
async_closure_sender: Some(async_closure_sender),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_from_file(
|
||||||
|
mize: &mut Mize,
|
||||||
|
name: &'static str,
|
||||||
|
code: FastStaticString,
|
||||||
|
) -> MizeResult<()> {
|
||||||
|
let mut js = mize.get_part_native::<JsPart>("js")?;
|
||||||
|
js.with_runtime_async(move |runtime: &mut JsRuntime| {
|
||||||
|
let module_spec = ModuleSpecifier::from_str(name).unwrap();
|
||||||
|
return Box::pin(async move {
|
||||||
|
runtime
|
||||||
|
.load_side_es_module_from_code(&module_spec, code)
|
||||||
|
.await;
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
impl JsPart {
|
impl JsPart {
|
||||||
|
/*
|
||||||
pub fn part_from_js_file(
|
pub fn part_from_js_file(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
@@ -66,12 +82,32 @@ impl JsPart {
|
|||||||
js_file: path,
|
js_file: path,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn runtime(&mut self) -> &mut JsRuntime {
|
*/
|
||||||
&mut self.js_runtime
|
pub fn with_runtime<T: FnOnce(&mut JsRuntime) -> MizeResult<()> + Send + 'static>(
|
||||||
|
&mut self,
|
||||||
|
func: T,
|
||||||
|
) {
|
||||||
|
self.closure_sender
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.send(Box::new(func))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
pub fn with_runtime_async<F>(&mut self, func: F)
|
||||||
|
where
|
||||||
|
F: for<'a> FnOnce(&'a mut JsRuntime) -> BoxFuture<'a> + Send + 'static,
|
||||||
|
{
|
||||||
|
self.async_closure_sender
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.send(Box::new(func))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[mize_part]
|
#[mize_part]
|
||||||
|
#[derive(Default)]
|
||||||
struct PartFromJsFileAdapter {
|
struct PartFromJsFileAdapter {
|
||||||
mize: Mize,
|
mize: Mize,
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
@@ -93,20 +129,20 @@ impl MizePart for PartFromJsFileAdapter {
|
|||||||
r#"
|
r#"
|
||||||
import {{ opts, deps, create }} from "{path}";
|
import {{ opts, deps, create }} from "{path}";
|
||||||
|
|
||||||
const isPromise = (value) => {
|
const isPromise = (value) => {{
|
||||||
return !!value && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function';
|
return !!value && (typeof value === 'object' || typeof value === 'function') && typeof value.then === 'function';
|
||||||
};
|
}};
|
||||||
|
|
||||||
// Call the async function
|
// Call the async function
|
||||||
let create_result = create(mize);
|
let create_result = create(mize);
|
||||||
if (isPromise(create_result)) {
|
if (isPromise(create_result)) {{
|
||||||
create_result = await create_result;
|
create_result = await create_result;
|
||||||
}
|
}}
|
||||||
const result = {
|
const result = {{
|
||||||
opts: opts(mize),
|
opts: opts(mize),
|
||||||
deps: deps(mize),
|
deps: deps(mize),
|
||||||
create: create_result,
|
create: create_result,
|
||||||
};
|
}};
|
||||||
|
|
||||||
result;
|
result;
|
||||||
"#
|
"#
|
||||||
@@ -142,7 +178,7 @@ impl MizePart for PartFromJsFileAdapter {
|
|||||||
let result = js.runtime().execute_script("[main]", js_code)?;
|
let result = js.runtime().execute_script("[main]", js_code)?;
|
||||||
|
|
||||||
// Resolve the promise and run event loop
|
// Resolve the promise and run event loop
|
||||||
let resolved_value = js.runtime.resolve_value(result).await?;
|
let resolved_value = js.runtime().resolve_value(result).await?;
|
||||||
|
|
||||||
// Run the event loop to completion
|
// Run the event loop to completion
|
||||||
js.runtime()
|
js.runtime()
|
||||||
@@ -153,3 +189,37 @@ impl MizePart for PartFromJsFileAdapter {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
fn js_runtime_thread(
|
||||||
|
mize: Mize,
|
||||||
|
closure_receiver: flume::Receiver<Box<dyn FnOnce(&mut JsRuntime) -> MizeResult<()> + Send>>,
|
||||||
|
async_closure_receiver: flume::Receiver<BoxClosure>,
|
||||||
|
) -> MizeResult<()> {
|
||||||
|
let mut js_runtime = JsRuntime::new(RuntimeOptions {
|
||||||
|
module_loader: Some(Rc::new(FsModuleLoader)),
|
||||||
|
extensions: vec![glue_deno::my_extension::init(mize.clone())],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
let poll_opts = PollEventLoopOptions::default();
|
||||||
|
|
||||||
|
let tokio_runtime = Builder::new_current_thread().enable_all().build().unwrap();
|
||||||
|
|
||||||
|
let local = LocalSet::new();
|
||||||
|
local.block_on(&tokio_runtime, async move {
|
||||||
|
loop {
|
||||||
|
// Drain queued closures quickly (no await here if possible)
|
||||||
|
if let Ok(func) = closure_receiver.recv_async().await {
|
||||||
|
if let Err(e) = func(&mut js_runtime) {
|
||||||
|
mize.report_err(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drive JS one tick
|
||||||
|
let _ = futures::future::poll_fn(|cx| js_runtime.poll_event_loop(cx, poll_opts)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
10
packages/marts/js/stub_deno.ts
Normal file
10
packages/marts/js/stub_deno.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export class Mize {
|
||||||
|
async get_config(key: string): Promise<any> {
|
||||||
|
return "hiiiiiii";
|
||||||
|
}
|
||||||
|
async add_opts(opts: any): Promise<void> {}
|
||||||
|
async add_part(part: any): Promise<void> {}
|
||||||
|
async report_err(err: MizeError) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
type MizeError = string;
|
||||||
@@ -1,6 +1,17 @@
|
|||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
mod cli;
|
mod cli;
|
||||||
#[cfg(feature = "target-os")]
|
#[cfg(feature = "target-os")]
|
||||||
pub use cli::*;
|
pub use cli::cli;
|
||||||
|
|
||||||
//mod js;
|
mod js;
|
||||||
|
|
||||||
|
#[cfg(feature = "target-os")]
|
||||||
|
pub fn habitica(mize: &mut mize::Mize) {
|
||||||
|
use deno_core::{ascii_str_include, include_js_files};
|
||||||
|
|
||||||
|
js::part_from_file(
|
||||||
|
mize,
|
||||||
|
"habitica",
|
||||||
|
ascii_str_include!("./deno_dist/habitica.js"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
5
packages/mize/deno.json
Normal file
5
packages/mize/deno.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "@ppc/mize",
|
||||||
|
"imports": {},
|
||||||
|
"exports": {}
|
||||||
|
}
|
||||||
8
packages/mize/main.ts
Normal file
8
packages/mize/main.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function add(a: number, b: number): number {
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Learn more at https://docs.deno.com/runtime/manual/examples/module_metadata#concepts
|
||||||
|
if (import.meta.main) {
|
||||||
|
console.log("Add 2 + 3 =", add(2, 3));
|
||||||
|
}
|
||||||
6
packages/mize/main_test.ts
Normal file
6
packages/mize/main_test.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { assertEquals } from "@std/assert";
|
||||||
|
import { add } from "./main.ts";
|
||||||
|
|
||||||
|
Deno.test(function addTest() {
|
||||||
|
assertEquals(add(2, 3), 5);
|
||||||
|
});
|
||||||
@@ -3,6 +3,7 @@ use colored::Colorize;
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use flume::{bounded, unbounded, Receiver, Sender};
|
use flume::{bounded, unbounded, Receiver, Sender};
|
||||||
use interner::shared::{StringPool, VecStringPool};
|
use interner::shared::{StringPool, VecStringPool};
|
||||||
|
use mize_macros::mize_part;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::create_dir;
|
use std::fs::create_dir;
|
||||||
@@ -860,6 +861,38 @@ impl Mize {
|
|||||||
part: Some(*concrete_part),
|
part: Some(*concrete_part),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
pub fn add_name_only_part(&mut self, name: &'static str) {
|
||||||
|
let part = NameOnlyPart {
|
||||||
|
mize: self.clone(),
|
||||||
|
name,
|
||||||
|
};
|
||||||
|
self.add_part(Box::new(part));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
struct NameOnlyPart {
|
||||||
|
mize: Mize,
|
||||||
|
name: &'static str,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MizePart for NameOnlyPart {}
|
||||||
|
impl MizePartGenerated for NameOnlyPart {
|
||||||
|
fn as_any_generated(&self) -> &dyn Any {
|
||||||
|
self.as_any()
|
||||||
|
}
|
||||||
|
fn as_any_mut_generated(&mut self) -> &mut dyn Any {
|
||||||
|
self.as_any_mut()
|
||||||
|
}
|
||||||
|
fn get_mize_generated(&mut self) -> &mut Mize {
|
||||||
|
&mut self.mize
|
||||||
|
}
|
||||||
|
fn into_any_generated(self: Box<Self>) -> Box<dyn Any> {
|
||||||
|
self.into_any()
|
||||||
|
}
|
||||||
|
fn name_generated(&self) -> &'static str {
|
||||||
|
self.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Mize {
|
impl fmt::Debug for Mize {
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ wasm-bindgen = { version = "0.2.108", optional = true }
|
|||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "ppc"
|
name = "ppc"
|
||||||
path = "src/platform/os/main.rs"
|
path = "platform/os/main.rs"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
name = "ppc"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["target-os"]
|
default = ["target-os"]
|
||||||
target-os = [ "clap", "mize/target-os" ]
|
target-os = [ "clap", "mize/target-os", "marts/target-os" ]
|
||||||
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-wasm", "marts/target-wasm" ]
|
target-obsidian = [ "js-sys", "wasm-bindgen", "mize/target-wasm", "marts/target-wasm" ]
|
||||||
|
|
||||||
[package.metadata.wasm-pack.profile.release]
|
[package.metadata.wasm-pack.profile.release]
|
||||||
|
|||||||
Reference in New Issue
Block a user