nuverse 0.1.0__tar.gz

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.
@@ -0,0 +1,99 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ share/python-wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+
28
+ # Installer logs
29
+ pip-log.txt
30
+ pip-delete-this-directory.txt
31
+
32
+ # Unit test / coverage reports
33
+ htmlcov/
34
+ .tox/
35
+ .nox/
36
+ .coverage
37
+ .coverage.*
38
+ .cache
39
+ nosetests.xml
40
+ coverage.xml
41
+ *.cover
42
+ *.py,cover
43
+ .hypothesis/
44
+ .pytest_cache/
45
+ cover/
46
+
47
+ # Environments
48
+ .env
49
+ .venv
50
+ env/
51
+ venv/
52
+ ENV/
53
+ env.bak/
54
+ venv.bak/
55
+
56
+ # uv
57
+ uv.lock
58
+
59
+ # mypy
60
+ .mypy_cache/
61
+ .dmypy.json
62
+ dmypy.json
63
+
64
+ # IDEs
65
+ .idea/
66
+ .vscode/
67
+
68
+ .DS_Store
69
+
70
+ # Profiling
71
+ *.prof
72
+ *.lprof
73
+
74
+ # Benchmarking
75
+ benchmark_results/
76
+ *.benchmark
77
+ *.benchmarks
78
+
79
+ # Ruff
80
+ .ruff_cache/
81
+
82
+ # Misc
83
+ /*playground
84
+ .db*/
85
+ .state*/
86
+ .logs*/
87
+
88
+ # syncthing
89
+ .stfolder
90
+
91
+ # nuspace-ui (vite / node)
92
+ node_modules/
93
+ !src/nuspace/web/ui/dist/
94
+ src/nuspace/web/ui/dist/*
95
+ !src/nuspace/web/ui/dist/.gitkeep
96
+
97
+ *.db/
98
+ # local archive of the v0 prototype (reference only, never edited)
99
+ _archive/
nuverse-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.5
2
+ Name: nuverse
3
+ Version: 0.1.0
4
+ Summary: nuspace extensions: the apps and snippets a space offers out of the box.
5
+ Project-URL: Repository, https://github.com/nustackdev/nuspace
6
+ Author-email: Gor Arakelyan <gorarkln@gmail.com>
7
+ License-Expression: AGPL-3.0-or-later
8
+ Requires-Python: >=3.10
9
+ Requires-Dist: nuspace
10
+ Description-Content-Type: text/markdown
11
+
12
+ # nuverse
13
+
14
+ The extensions a [nuspace](https://github.com/nustackdev/nuspace) space offers out of the box: the apps `+` makes and the snippets `/` inserts.
15
+
16
+ nuspace finds it on install through the `nuspace.extensions` entry point. You don't import it yourself.
17
+
18
+ ```
19
+ pip install nuspace
20
+ ```
21
+
22
+ Early. It tracks nuspace's unreleased v4 and needs it to be useful.
@@ -0,0 +1,11 @@
1
+ # nuverse
2
+
3
+ The extensions a [nuspace](https://github.com/nustackdev/nuspace) space offers out of the box: the apps `+` makes and the snippets `/` inserts.
4
+
5
+ nuspace finds it on install through the `nuspace.extensions` entry point. You don't import it yourself.
6
+
7
+ ```
8
+ pip install nuspace
9
+ ```
10
+
11
+ Early. It tracks nuspace's unreleased v4 and needs it to be useful.
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "nuverse"
7
+ version = "0.1.0"
8
+ description = "nuspace extensions: the apps and snippets a space offers out of the box."
9
+ readme = "README.md"
10
+ license = "AGPL-3.0-or-later"
11
+ authors = [{ name = "Gor Arakelyan", email = "gorarkln@gmail.com" }]
12
+ requires-python = ">=3.10"
13
+ dependencies = [
14
+ # nuverse imports nuspace, nuspace never imports nuverse: it finds this
15
+ # package through the entry point below, the same one a third party uses.
16
+ "nuspace",
17
+ ]
18
+
19
+ [project.urls]
20
+ Repository = "https://github.com/nustackdev/nuspace"
21
+
22
+ [project.entry-points."nuspace.extensions"]
23
+ nuverse = "nuverse:extension"
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src/nuverse"]
27
+
28
+ [tool.uv.sources]
29
+ nuspace = { workspace = true }
@@ -0,0 +1,31 @@
1
+ """nuverse: the extensions a space offers out of the box.
2
+
3
+ - :mod:`.apps`: what ``+`` makes: ``page``, and later ``job``, ``chat``.
4
+ - :mod:`.snippets`: what ``/`` inserts: ``prose``, ``program``, ``ticker``,
5
+ and later ``heading``, ``monaco``.
6
+
7
+ nuspace finds this package through the ``nuspace.extensions`` entry point,
8
+ which names :func:`extension`. Nothing is imported here at module scope:
9
+ workers import cell programs, and a program never needs the registry.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ from typing import TYPE_CHECKING
15
+
16
+
17
+ if TYPE_CHECKING:
18
+ from nuspace import Extension
19
+
20
+
21
+ __all__ = ["extension"]
22
+
23
+
24
+ def extension() -> Extension:
25
+ """Every nuverse app and snippet, as one extension."""
26
+ from nuspace import Extension
27
+
28
+ from .apps import APPS
29
+ from .snippets import SNIPPETS
30
+
31
+ return Extension(apps=APPS, snippets=SNIPPETS, envs={})
@@ -0,0 +1,16 @@
1
+ """The apps ``+`` makes, one module each.
2
+
3
+ Every module defines ``APP``: an :class:`~nuspace.App`, or None while it is
4
+ still a placeholder, which is left out.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from . import chat, job, page
10
+
11
+
12
+ __all__ = ["APPS"]
13
+
14
+
15
+ #: Every app ready to register, in picker order.
16
+ APPS = tuple(module.APP for module in (page, job, chat) if module.APP is not None)
@@ -0,0 +1,19 @@
1
+ """The ``chat`` app. Placeholder.
2
+
3
+ TODO: another agent fills this in. Until then ``APP`` is None and the app is
4
+ left out of :data:`nuverse.apps.APPS`.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from nuspace import App
14
+
15
+
16
+ __all__ = ["APP"]
17
+
18
+
19
+ APP: App | None = None
@@ -0,0 +1,19 @@
1
+ """The ``job`` app. Placeholder.
2
+
3
+ TODO: another agent fills this in. Until then ``APP`` is None and the app is
4
+ left out of :data:`nuverse.apps.APPS`.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import TYPE_CHECKING
10
+
11
+
12
+ if TYPE_CHECKING:
13
+ from nuspace import App
14
+
15
+
16
+ __all__ = ["APP"]
17
+
18
+
19
+ APP: App | None = None
@@ -0,0 +1,26 @@
1
+ """The ``page`` app: a plane of cells the sidebar lists under Pages."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from nuspace import App, ops
8
+
9
+
10
+ if TYPE_CHECKING:
11
+ import nu
12
+
13
+
14
+ __all__ = ["APP", "page"]
15
+
16
+
17
+ #: What the page app marks its planes with: drawn, listed, editable.
18
+ META = {"ui": True, "made_by": "page", "editable": True}
19
+
20
+
21
+ def page(plane_id: nu.StrArg | None = None, name: nu.StrArg = "") -> nu.Nu:
22
+ """A page plane. Yields its id, as :func:`~nuspace.ops.add_plane` does."""
23
+ return ops.add_plane(plane_id, name=name, meta=META)
24
+
25
+
26
+ APP = App("page", "Pages", page, description="A plane of cells.")
@@ -0,0 +1,21 @@
1
+ """The snippets ``/`` inserts, one module each.
2
+
3
+ Every module defines ``SOURCE``, the cell's prog, and ``SNIPPET``: a
4
+ :class:`~nuspace.Snippet` over it, or None while it is still a placeholder,
5
+ which is left out.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from . import heading, monaco, program, prose, ticker
11
+
12
+
13
+ __all__ = ["SNIPPETS"]
14
+
15
+
16
+ #: Every snippet ready to register, in menu order.
17
+ SNIPPETS = tuple(
18
+ module.SNIPPET
19
+ for module in (prose, heading, program, ticker, monaco)
20
+ if module.SNIPPET is not None
21
+ )
@@ -0,0 +1,22 @@
1
+ """The ``heading`` snippet. Placeholder.
2
+
3
+ TODO: another agent fills this in. Until then ``SOURCE`` is empty,
4
+ ``SNIPPET`` is None and the snippet is left out of
5
+ :data:`nuverse.snippets.SNIPPETS`.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+
13
+ if TYPE_CHECKING:
14
+ from nuspace import Snippet
15
+
16
+
17
+ __all__ = ["SNIPPET", "SOURCE"]
18
+
19
+
20
+ SOURCE = ""
21
+
22
+ SNIPPET: Snippet | None = None
@@ -0,0 +1,22 @@
1
+ """The ``monaco`` snippet. Placeholder.
2
+
3
+ TODO: another agent fills this in. Until then ``SOURCE`` is empty,
4
+ ``SNIPPET`` is None and the snippet is left out of
5
+ :data:`nuverse.snippets.SNIPPETS`.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import TYPE_CHECKING
11
+
12
+
13
+ if TYPE_CHECKING:
14
+ from nuspace import Snippet
15
+
16
+
17
+ __all__ = ["SNIPPET", "SOURCE"]
18
+
19
+
20
+ SOURCE = ""
21
+
22
+ SNIPPET: Snippet | None = None
@@ -0,0 +1,29 @@
1
+ """The ``program`` snippet: what a fresh code cell starts as.
2
+
3
+ One key in its own state, then done.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from nuspace import Snippet
9
+
10
+
11
+ __all__ = ["SNIPPET", "SOURCE"]
12
+
13
+
14
+ SOURCE = """\
15
+ import nu
16
+ import nustd.kv
17
+ import nuspace
18
+
19
+
20
+ class Note(nuspace.CellState):
21
+ hello = nustd.kv.StrRef.slot()
22
+
23
+
24
+ def out():
25
+ # Bare state: the kernel lands it under this cell, whichever it is.
26
+ return Note.hello.set(nu.Str("world"))
27
+ """
28
+
29
+ SNIPPET = Snippet("program", "Program", SOURCE)
@@ -0,0 +1,44 @@
1
+ """The ``prose`` snippet: a document cell.
2
+
3
+ One prose surface over a string in its own state, synced both ways. Every
4
+ prose cell holds exactly this prog, and that is how the viewer tells one
5
+ apart: what the person wrote lives in the state, not here.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from nuspace import Snippet
11
+
12
+
13
+ __all__ = ["SNIPPET", "SOURCE"]
14
+
15
+
16
+ SOURCE = """\
17
+ import nu
18
+ import nustd.kv
19
+ import nustd.ui
20
+ import nuspace
21
+
22
+
23
+ class Doc(nuspace.CellState):
24
+ text = nustd.kv.StrRef.slot()
25
+
26
+
27
+ def out():
28
+ body = nustd.ui.ProseRef("text")
29
+ held = nu.If(Doc.text.exists(), nu.ToStr(Doc.text), nu.Str(""))
30
+ return (
31
+ body.set(held)
32
+ >> body.set_placeholder(nu.Str("Write, or press / for blocks"))
33
+ >> nu.ParallelAsync(
34
+ # This tab typed: keep it. Every other tab on the plane hears it
35
+ # through the store.
36
+ nu.ReactForever(body.on_change(), Doc.text.set(nu.Str(body))),
37
+ # Somebody else typed: show it. The echo back to the author is a
38
+ # no-op, the text is already what it says.
39
+ nu.ReactForever(Doc.text.on_change(), body.set(nu.ToStr(Doc.text))),
40
+ )
41
+ )
42
+ """
43
+
44
+ SNIPPET = Snippet("prose", "Text", SOURCE)
@@ -0,0 +1,33 @@
1
+ """The ``ticker`` snippet: a cell that draws.
2
+
3
+ One stat tile, and a count kept in its own state, one a second while the
4
+ plane is up.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from nuspace import Snippet
10
+
11
+
12
+ __all__ = ["SNIPPET", "SOURCE"]
13
+
14
+
15
+ SOURCE = """\
16
+ import nu
17
+ import nustd.kv
18
+ import nustd.ui
19
+ import nuspace
20
+
21
+
22
+ class Tick(nuspace.CellState):
23
+ n = nustd.kv.IntRef.slot()
24
+
25
+
26
+ def out():
27
+ tile = nustd.ui.StatRef("seconds")
28
+ now = nu.If(Tick.n.exists(), nu.Int(nu.ToInt(Tick.n)), nu.Int(0))
29
+ step = Tick.n.set(now + nu.Int(1)) >> tile.set_value(nu.ToStr(Tick.n))
30
+ return tile.set_label("seconds this plane was open") >> nu.ForeverDo(nu.DelayedDo(1.0, step))
31
+ """
32
+
33
+ SNIPPET = Snippet("ticker", "Ticker", SOURCE)