Metadata-Version: 2.3
Name: Python-JavaScript
Version: 0.2.0
Summary: JavaScript-style Python values and a bounded Python-to-JavaScript browser compiler
Keywords: javascript,ecmascript,objects,arrays
Author: ellainng
Author-email: ellainng <299958882+ellainng@users.noreply.github.com>
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: javascript-fetch-api>=0.2.0,<0.3.0
Requires-Dist: javascript-json>=0.1.0,<0.2.0
Requires-Python: >=3.14
Project-URL: Homepage, https://github.com/outside-labs/Python-JavaScript
Project-URL: Repository, https://github.com/outside-labs/Python-JavaScript
Project-URL: Issues, https://github.com/outside-labs/Python-JavaScript/issues
Description-Content-Type: text/markdown

# Python-JavaScript

JavaScript-style objects, methods and functions for Python 3.14+, using the
case-sensitive `JavaScript` namespace. An alpha compatibility layer with a
documented subset of ECMAScript behavior.

```sh
python -m pip install Python-JavaScript==0.2.0
```

```python
from JavaScript import Array, JSON, Math, Object, String, undefined

people = JSON.parse('[{"name":"Ada","score":8},{"name":"Lin","score":6}]')
names = people.filter(lambda person: person.score >= 7).map(
    lambda person: person.name.toUpperCase()
)
assert names.join(", ") == "ADA"

profile = Object({"name": String("Ada"), "scores": Array.of(8, 6)})
assert profile.missing is undefined
assert profile.scores.reduce(lambda total, score: total + score, 0) == 14
assert Math.round(2.5) == 3
assert JSON.stringify(profile) == '{"name":"Ada","scores":[8,6]}'
```

Explicit `Object`, `Array`, `String` and `Number` values expose JavaScript names
and behavior. Ordinary Python literals and operators retain Python semantics.
Objects and arrays compare by identity and remain truthy when empty. Use
`Boolean(value)` or `truthy(value)` when testing JavaScript truthiness of values
that might include Python containers.

## Standalone packages

Installation includes two independently useful dependencies:

| Distribution | Import | Purpose |
| --- | --- | --- |
| `JavaScript-Fetch-API>=0.2.0,<0.3.0` | `fetch_api` | Standard-library HTTP Fetch and Promise APIs |
| `JavaScript-JSON>=0.1.0,<0.2.0` | `JSON` | Python-friendly JSON parsing, serialization and dot traversal |

```python
import asyncio
from fetch_api import fetch
from JavaScript import JSON

async def main():
    response = await fetch("https://example.com/api/people")
    if not response.ok:
        raise RuntimeError(f"HTTP {response.status}")
    people = JSON.parse(await response.text())
    return people

# Run against your own JSON endpoint:
# people = asyncio.run(main())
```

`JavaScript.fetch`, `Promise`, `Headers`, `Request`, `Response` and `FetchError`
are the same objects exported by `fetch_api`. Fetch 0.2.0 changes the old
`from javascript import fetch` spelling to `from fetch_api import fetch`.

`response.json()` retains Fetch's standalone `JSONObject`/list result. Use
`JavaScript.JSON.parse(await response.text())` for runtime Object/Array/String
values. Standalone `import JSON` preserves Python integers and containers;
`from JavaScript import JSON` uses binary64 numbers and JavaScript serialization
rules for its supported subset.

## Supported surface

Core data objects and sparse arrays; UTF-16 String methods; Number predicates and
prefix parsers; Boolean conversion; selected Math functions; JSON; and the
standalone Fetch/Promise APIs. See the complete
[compatibility matrix](docs/compatibility.md) for method lists and limits.

Python keywords require `Array.from_`, `Object.is_`, and `Promise.finally_`.
`None` represents `null`; `undefined` is a separate singleton. Array bracket
indices follow JavaScript rules: `values[-1]` is a named property, and
`values.at(-1)` accesses the last element. `Array(3)` creates three holes;
`Array.of(3)` creates one element containing 3.

Version 0.2.0 also includes a bounded Python-to-JavaScript compiler: a
[binding-aware front end](docs/compiler-front-end.md), [ES module emitter](docs/compiler-emitter.md),
[local-module compiler](docs/compiler-modules.md), [async profile](docs/compiler-async.md)
and [browser worker/host target](docs/compiler-browser.md). Python parses source
at build time; generated modules and selected helpers execute on the client.
The separate pocket-python interpreter will parse newly entered Python in the browser.

```python
from JavaScript.emitter import compile_source

artifact = compile_source("def count(text):\n    return len(text)", filename="counter.py")
# artifact.files contains emitted JavaScript, source map and provenance notice.
```

This alpha supports the explicit [compiler language](docs/compiler-language.md),
not arbitrary Python dependencies or complete ECMAScript. Prototypes, descriptors,
Date, RegExp, Map/Set, typed arrays and unlisted APIs remain future work. See
[0.2.0 release notes](docs/release-0.2.0.md), the [implementation plan](IMPLEMENTATION_PLAN.md),
[issues](https://github.com/outside-labs/Python-JavaScript/issues) and
[Project](https://github.com/orgs/outside-labs/projects/11).

## Development

```sh
uv sync
uv run python -m unittest discover -s tests -v
uv build
```

Node.js 24 runs the native ECMAScript differential fixture. That test is skipped
when Node is absent locally; CI and release builds require it. Runtime code
needs only Python and the two declared companions. Tests make no external
network requests.

The [compiler emitter](docs/compiler-emitter.md) produces deterministic
ES modules for the approved single-module Python profile. The compiler APIs are included in the 0.2.0 distribution.

The explicit [async compiler profile](docs/compiler-async.md) adds lazy coroutines,
awaited Promise values, callbacks and context cancellation. The [browser target](docs/compiler-browser.md) adds named DOM controls, callbacks,
native Fetch text and worker stop/restart.

Build the local [text_metrics browser example](docs/compiler-browser.md#run-the-example)
with `uv run python examples/browser_text_metrics.py --output build/browser-text-metrics`.
It uses our emitted modules and helpers in a worker; source parsing remains the
separate independent-interpreter milestone.

The compiler has a versioned [CPython/Node/browser parity suite](docs/compiler-conformance.md) with typed results, source-map error checks and explicit unsupported boundaries.
