Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,49 @@ ECMAScript interpreter for Cython & Python built for
- Being a good companion alongside [selectolax](https://github.com/rushter/selectolax) or beautiful-soup the choice is yours...
- License friendly, after abandoning pyduktape due to the backend no longer being maintained but also having a pretty poor license all together, It inspired me to try something new for a change that could run newer HTML5 Javascript for any puzzle that is thrown your way.

## Installation
Installation of cyjs is pretty simplistic and you can get the released version from pypi
```
pip install cyjs
```

### Using Unreleased Development Versions
If your planning to contribute or want in on anything newly
added you can clone the github repo there is however one
dependency needed which is CMake, it was chosen to keep the
setuptools section cleansed and allow the quickjs-ng contributors to help us with those sections.
You can install cmake using pip if you need something lazy and quick. It's recommended you install cmake globally if you don't have it yet.

```
pip install cmake
```

### UV (Recommended)
After getting cmake it is recommended to use uv to build and
install the cyjs library in development mode

```
uv sync
```
Otherwise you can try this approch know that you need pytest if your planning to test anything locally.

1.
```
uv venv
```

2.
```
uv pip install -e .
```

### Alternative Route

```
pip install -e .
```


## Quick Example


Expand Down
2 changes: 1 addition & 1 deletion cyjs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
)

__author__ = "Vizonex"
__version__ = "0.2.1"
__version__ = "0.3.0"

__all__ = (
"CancelledError",
Expand Down
3 changes: 3 additions & 0 deletions cyjs/_cyjs.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,6 @@ cdef class Context:
JSClass js_cls
)

# Privated away from python, it's just a fancy
# little shortcut
cdef void free_value(self, JSValue value)
14 changes: 14 additions & 0 deletions cyjs/_cyjs.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class Context:
backtrace_barrier: bool = ...,
promise: bool = ...,
) -> Any: ...

def add_class(self, js_cls: JSClass[Any]):
"""
binds a JSClass Globally to globalThis
Expand All @@ -272,6 +273,19 @@ class Context:
attribute of this context \
as a shortcut and calling `runtime.new_class(...)` beforehand
"""

def set_script_arguments(self, *args: str):
"""adds script arguments simillar to js_std_add_helpers however
it only sends in the "scriptArgs" data, if empty
this will be an empty array."""

def add_std_print_handlers(self):
"""
implements console printing functions.
"""

def add_std_helpers(self, *args):
"""functions the same as js_std_add_helpers."""

class CancelledError(Exception):
"""Promise was rejected"""
Expand Down
32 changes: 29 additions & 3 deletions cyjs/_cyjs.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ from cpython.buffer cimport PyObject_CheckBuffer
from cpython.bytes cimport PyBytes_FromStringAndSize
from cpython.exc cimport (PyErr_CheckSignals, PyErr_NoMemory, PyErr_Occurred,
PyErr_SetObject, PyErr_WriteUnraisable)
from cpython.list cimport PyList_AsTuple
from cpython.list cimport PyList_AsTuple, PyList_GET_SIZE
from cpython.long cimport PyLong_AsLongAndOverflow, PyLong_FromString
from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc
from cpython.object cimport PyObject_CallObject, PyObject_Str, Py_TYPE, PyObject_GetAttr, PyObject_SetAttr, PyObject_HasAttrString
from cpython.list cimport PyList_GET_SIZE
from cpython.object cimport (Py_TYPE, PyObject_CallObject, PyObject_GetAttr,
PyObject_HasAttrString, PyObject_SetAttr,
PyObject_Str)
from cpython.tuple cimport PyTuple_GET_SIZE
from cpython.type cimport PyType_Check
from cpython.unicode cimport PyUnicode_FromString, PyUnicode_FromStringAndSize
Expand Down Expand Up @@ -1412,6 +1413,31 @@ cdef class Context: # type: ignore

return to_python(self.ctx, obj)

cdef void free_value(self, JSValue value):
JS_FreeValue(self.ctx, value)

def set_script_arguments(self, *args):
"""adds script arguments simillar to js_std_add_helpers however
it only sends in the "scriptArgs" data, if empty
this will be an empty array."""
self.set("scriptArgs", list(args))

def add_std_print_handlers(self):
"""
implements console printing functions.
"""
# NOTE: We can ignore argc, argv we have a faster method
# for that...
js_std_add_helpers(self.ctx, 0, NULL)

def add_std_helpers(self, *args):
"""functions the same as js_std_add_helpers."""
js_std_add_helpers(self.ctx, 0, NULL)
self.set("scriptArgs", list(args))






# TODO: Soon as I figure out how to make callbacks and promises work...
Expand Down
64 changes: 63 additions & 1 deletion cyjs/quickjs.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ cdef extern from "quickjs.h" nogil:
void JS_ComputeMemoryUsage(JSRuntime*, JSMemoryUsage*)
void JS_DumpMemoryUsage(FILE*, JSMemoryUsage*, JSRuntime*)

# Pull request for this one is pending: SEE: https://github.com/quickjs-ng/quickjs/pull/1284
# Pull request for this one is pending: SEE: https:#github.com/quickjs-ng/quickjs/pull/1284
# ctypedef int (*JS_MemoryUsageCB)(void* opaque, const char* data, size_t data_len) noexcept with gil
# int JS_WriteMemoryUsage(JS_MemoryUsageCB cb, const JSMemoryUsage *s, JSRuntime *rt, void* opaque)
JSAtom JS_NewAtomLen(JSContext*, const char*, size_t)
Expand Down Expand Up @@ -558,6 +558,68 @@ cdef extern from "quickjs.h" nogil:
int JS_PROP_NORMAL
int JS_PROP_GETSET


ctypedef JSRuntime *(*runtime_func)()
ctypedef JSContext *(*context_func)(JSRuntime *rt)

cdef extern from "quickjs-libc.h":
ctypedef uint8_t *JSLoadFileFunc(JSContext *ctx, size_t *pbuf_len,
const char *filename)

JSModuleDef *js_init_module_std(
JSContext *ctx,
const char *module_name
)
JSModuleDef *js_init_module_os(
JSContext *ctx,
const char *module_name
)
JSModuleDef *js_init_module_bjson(
JSContext *ctx,
const char *module_name
)
void js_std_add_helpers(JSContext *ctx, int argc, char **argv)
int js_std_loop(JSContext *ctx)
int js_std_loop_once(JSContext *ctx)
int js_std_poll_io(JSContext *ctx, int timeout_ms)
JSValue js_std_await(JSContext *ctx, JSValue obj)
void js_std_init_handlers(JSRuntime *rt)
void js_std_free_handlers(JSRuntime *rt)
void js_std_dump_error(JSContext *ctx)
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len,
const char *filename)
int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
bool use_realpath, bool is_main)
JSModuleDef *js_module_loader(JSContext *ctx,
const char *module_name, void *opaque,
JSValue attributes)
# like js_module_loader but does not load .so objects and the file reader
# is pluggable; js_module_loader is implemented in terms of js_module_load
JSModuleDef *js_module_load(JSContext *ctx, const char *module_name,
void *opaque, JSValue attributes,
JSLoadFileFunc *load_file)
int js_module_check_attributes(JSContext *ctx, void *opaque,
JSValue attributes)
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf,
size_t buf_len, int flags)
void js_std_promise_rejection_tracker(JSContext *ctx,
JSValue promise,
JSValue reason,
bool is_handled,
void *opaque)
# Defaults to JS_NewRuntime, no-op if compiled without worker support.
# Call before creating the first worker thread.
void js_std_set_worker_new_runtime_func(runtime_func func);
# Defaults to JS_NewContext, no-op if compiled without worker support.
# Call before creating the first worker thread.

void js_std_set_worker_new_context_func(context_func func)









Loading
Loading