@gen3/workspaces 0.12.64 → 0.12.66

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.
Files changed (103) hide show
  1. package/TODO.md +6 -7
  2. package/dist/jupyterlite-builds/free-private/jupyter_lite_config.json +5 -19
  3. package/dist/jupyterlite-builds/free-private/requirements.txt +1 -1
  4. package/dist/jupyterlite-builds/remote-private/overrides.json +16 -0
  5. package/dist/jupyterlite-builds/scripts/build-gen3sdk-lite.sh +428 -0
  6. package/dist/jupyterlite-builds/scripts/build-jupyterlite.sh +150 -33
  7. package/dist/jupyterlite-builds/scripts/setup-env.sh +81 -0
  8. package/dist/jupyterlite-builds/scripts/sync-jupyter-assets-into-package.sh +19 -2
  9. package/dist/jupyterlite-builds/scripts/validate-jupyterlite-assets.sh +3 -0
  10. package/jupyterlite-builds/free-private/jupyter_lite_config.json +5 -19
  11. package/jupyterlite-builds/free-private/requirements.txt +1 -1
  12. package/jupyterlite-builds/remote-private/overrides.json +16 -0
  13. package/package.json +5 -3
  14. package/scripts/build-gen3sdk-lite.sh +428 -0
  15. package/scripts/build-jupyterlite.sh +150 -33
  16. package/scripts/patch-pyidode-lock.py +100 -0
  17. package/scripts/setup-env.sh +81 -0
  18. package/scripts/sync-jupyter-assets-into-package.sh +19 -2
  19. package/scripts/validate-jupyterlite-assets.sh +3 -0
  20. package/.jupyterlite.doit.db +0 -0
  21. package/dist/jupyterlite-builds/scripts/build-gen3sdk-lite_v2.sh +0 -310
  22. package/dist/jupyterlite-builds/scripts/build-jupyterlite_v2.sh +0 -111
  23. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/aiofiles-25.1.0-py3-none-any.whl +0 -0
  24. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/backoff-2.2.1-py3-none-any.whl +0 -0
  25. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/cdislogging-1.2.0-py3-none-any.whl +0 -0
  26. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/comm-0.2.3-py3-none-any.whl +0 -0
  27. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/dataclasses_json-0.5.9-py3-none-any.whl +0 -0
  28. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/dictionaryutils-4.0.0-py3-none-any.whl +0 -0
  29. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/drsclient-0.4.0-py3-none-any.whl +0 -0
  30. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/fastavro-1.12.2-py3-none-any.whl +0 -0
  31. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/gen3-4.28.3-py3-none-any.whl +0 -0
  32. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/gen3dictionary-3.0.0-py3-none-any.whl +0 -0
  33. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/gen3users-1.1.1-py3-none-any.whl +0 -0
  34. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/humanfriendly-10.0-py2.py3-none-any.whl +0 -0
  35. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/importlib_metadata-8.9.0-py3-none-any.whl +0 -0
  36. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/indexclient-6.3.0-py3-none-any.whl +0 -0
  37. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/ipykernel-6.9.2-py3-none-any.whl +0 -0
  38. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/ipython_pygments_lexers-1.1.1-py3-none-any.whl +0 -0
  39. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/marshmallow-3.26.2-py3-none-any.whl +0 -0
  40. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/marshmallow_enum-1.5.1-py2.py3-none-any.whl +0 -0
  41. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/mypy_extensions-1.1.0-py3-none-any.whl +0 -0
  42. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/piplite-0.8.5-py3-none-any.whl +0 -0
  43. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/pyodide_http-0.2.2-py3-none-any.whl +0 -0
  44. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/pyodide_kernel-0.8.5-py3-none-any.whl +0 -0
  45. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/pypfb-0.6.2-py3-none-any.whl +0 -0
  46. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/python_dateutil-2.9.0.post0-py2.py3-none-any.whl +0 -0
  47. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/python_json_logger-4.2.0-py3-none-any.whl +0 -0
  48. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/typing_inspect-0.9.0-py3-none-any.whl +0 -0
  49. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/xmltodict-0.13.0-py2.py3-none-any.whl +0 -0
  50. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_uv_wheels/zipp-4.1.0-py3-none-any.whl +0 -0
  51. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_work/constraints.txt +0 -354
  52. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_work/excludes.txt +0 -3
  53. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_work/pylock.toml +0 -347
  54. package/jupyterlite-builds/free-private/.cache/pyodide-lock/_work/requirements.in +0 -26
  55. package/jupyterlite-builds/free-private/.cache/pyodide-lock/patched-pyodide-lock.json +0 -1
  56. package/jupyterlite-builds/free-private/.cache/pyodide-lock/pyodide-lock.json +0 -1
  57. package/jupyterlite-builds/free-private/.cache/pyodide-lock/remote-pyodide-lock.json +0 -1
  58. package/jupyterlite-builds/free-private/.cache/wheels/aiofiles-25.1.0-py3-none-any.whl.meta.json +0 -24
  59. package/jupyterlite-builds/free-private/.cache/wheels/backoff-2.2.1-py3-none-any.whl.meta.json +0 -24
  60. package/jupyterlite-builds/free-private/.cache/wheels/cdislogging-1.2.0-py3-none-any.whl.meta.json +0 -24
  61. package/jupyterlite-builds/free-private/.cache/wheels/dataclasses_json-0.5.9-py3-none-any.whl.meta.json +0 -24
  62. package/jupyterlite-builds/free-private/.cache/wheels/dictionaryutils-4.0.0-py3-none-any.whl.meta.json +0 -24
  63. package/jupyterlite-builds/free-private/.cache/wheels/drsclient-0.4.0-py3-none-any.whl.meta.json +0 -24
  64. package/jupyterlite-builds/free-private/.cache/wheels/fastavro-1.12.2-py3-none-any.whl.meta.json +0 -24
  65. package/jupyterlite-builds/free-private/.cache/wheels/gen3-4.28.3-py3-none-any.whl.meta.json +0 -24
  66. package/jupyterlite-builds/free-private/.cache/wheels/gen3dictionary-3.0.0-py3-none-any.whl.meta.json +0 -24
  67. package/jupyterlite-builds/free-private/.cache/wheels/gen3users-1.1.1-py3-none-any.whl.meta.json +0 -24
  68. package/jupyterlite-builds/free-private/.cache/wheels/humanfriendly-10.0-py2.py3-none-any.whl.meta.json +0 -24
  69. package/jupyterlite-builds/free-private/.cache/wheels/importlib_metadata-8.9.0-py3-none-any.whl.meta.json +0 -24
  70. package/jupyterlite-builds/free-private/.cache/wheels/indexclient-6.3.0-py3-none-any.whl.meta.json +0 -24
  71. package/jupyterlite-builds/free-private/.cache/wheels/marshmallow-3.26.2-py3-none-any.whl.meta.json +0 -24
  72. package/jupyterlite-builds/free-private/.cache/wheels/marshmallow_enum-1.5.1-py2.py3-none-any.whl.meta.json +0 -24
  73. package/jupyterlite-builds/free-private/.cache/wheels/mypy_extensions-1.1.0-py3-none-any.whl.meta.json +0 -24
  74. package/jupyterlite-builds/free-private/.cache/wheels/pypfb-0.6.2-py3-none-any.whl.meta.json +0 -24
  75. package/jupyterlite-builds/free-private/.cache/wheels/python_dateutil-2.9.0.post0-py2.py3-none-any.whl.meta.json +0 -24
  76. package/jupyterlite-builds/free-private/.cache/wheels/python_json_logger-4.2.0-py3-none-any.whl.meta.json +0 -24
  77. package/jupyterlite-builds/free-private/.cache/wheels/typing_inspect-0.9.0-py3-none-any.whl.meta.json +0 -24
  78. package/jupyterlite-builds/free-private/.cache/wheels/xmltodict-0.13.0-py2.py3-none-any.whl.meta.json +0 -24
  79. package/jupyterlite-builds/free-private/.cache/wheels/zipp-4.1.0-py3-none-any.whl.meta.json +0 -24
  80. package/jupyterlite-builds/free-private/cockle-config.json +0 -71
  81. package/jupyterlite-builds/free-private/cockle_wasm_env/.mambarc +0 -1
  82. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/coreutils.js +0 -5421
  83. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/coreutils.wasm +0 -0
  84. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/fs.d.ts +0 -375
  85. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/fs.js +0 -3401
  86. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/fs.wasm +0 -0
  87. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/grep.js +0 -3839
  88. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/grep.wasm +0 -0
  89. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/less.data +0 -0
  90. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/less.js +0 -5060
  91. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/less.wasm +0 -0
  92. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/sed.js +0 -3843
  93. package/jupyterlite-builds/free-private/cockle_wasm_env/bin/sed.wasm +0 -0
  94. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/cockle_fs-0.3.0-h27506cd_2.json +0 -60
  95. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/coreutils-9.10-h072c4ef_3.json +0 -52
  96. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/emscripten-abi-4.0.9-h267e887_9.json +0 -31
  97. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/grep-3.12-h8b79025_0.json +0 -52
  98. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/history +0 -10
  99. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/less-693-hf259948_0.json +0 -60
  100. package/jupyterlite-builds/free-private/cockle_wasm_env/conda-meta/sed-4.9-h072c4ef_0.json +0 -52
  101. package/scripts/aiohttp-3.13.5-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
  102. package/scripts/build-gen3sdk-lite_v2.sh +0 -310
  103. package/scripts/build-jupyterlite_v2.sh +0 -111
@@ -1,18 +1,56 @@
1
1
  #!/usr/bin/env bash
2
+ # =============================================================================
3
+ # build-jupyterlite.sh — Build a JupyterLite site (free or remote tier)
4
+ #
5
+ # Sources setup-env.sh so the venv, Python version, and tooling are identical
6
+ # to those used by build-gen3sdk-lite.sh.
7
+ #
8
+ # Package delivery model (see jupyter_lite_config.json):
9
+ # - PyodideAddon vendors the full Pyodide distribution into static/pyodide,
10
+ # so the runtime and its ~300 wheels are served from our own origin.
11
+ # - PyodideLockAddon is DISABLED. In jupyterlite-pyodide-kernel 0.8.5 its
12
+ # post_build_lock() copies the lock away from the wheels it references,
13
+ # so a vendored local distribution fails with Pep508UrlError. The
14
+ # distribution's own pyodide-lock.json is shipped untouched instead.
15
+ # - Our wheels reach the browser via PipliteAddon, fed by the
16
+ # --piplite-wheels flags below.
17
+ #
18
+ # Usage:
19
+ # ./build-jupyterlite.sh <tier> [build_dir]
20
+ # tier: 'free' or 'remote'
21
+ # =============================================================================
2
22
  set -euo pipefail
3
23
 
24
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
+
4
26
  usage() {
5
27
  echo "Usage: $0 <tier> [build_dir]"
6
- echo " tier: 'free' or 'remote'"
28
+ echo " tier: 'free' or 'remote'"
7
29
  exit 1
8
30
  }
9
31
 
32
+ # ── Parse flags (strip before positional args are consumed) ──────────────────
33
+ POSITIONAL_ARGS=()
34
+ for _arg in "$@"; do
35
+ case "$_arg" in
36
+ # Accepted and ignored for backwards compatibility. This used to skip
37
+ # downloading CDN wheels and patching pyodide-lock.json; that step is gone
38
+ # because the Pyodide distribution is now vendored at build time.
39
+ --no-extras)
40
+ echo "[WARN] --no-extras is obsolete and has no effect; remove it from package.json"
41
+ ;;
42
+ *) POSITIONAL_ARGS+=("$_arg") ;;
43
+ esac
44
+ done
45
+ set -- "${POSITIONAL_ARGS[@]+"${POSITIONAL_ARGS[@]}"}"
46
+
10
47
  TIER="${1:-}"
11
48
  if [[ "$TIER" != "free" && "$TIER" != "remote" ]]; then
12
49
  usage
13
50
  fi
14
51
 
15
- ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
52
+ # ── Path constants (self-contained, mirrors build-gen3sdk-lite layout) ───────
53
+ ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
16
54
 
17
55
  if [[ "$TIER" == "free" ]]; then
18
56
  SRC_DIR="$ROOT_DIR/free-private"
@@ -20,47 +58,126 @@ else
20
58
  SRC_DIR="$ROOT_DIR/remote-private"
21
59
  fi
22
60
 
61
+ _resolve_against_init_cwd() {
62
+ local path="$1"
63
+ local base="${INIT_CWD:-$(pwd)}"
64
+ case "$path" in
65
+ /*) printf '%s' "$path" ;;
66
+ *) printf '%s/%s' "$base" "$path" ;;
67
+ esac
68
+ }
69
+
70
+ BUILD_DIR="$(_resolve_against_init_cwd "${2:-builds}")"
71
+ mkdir -p "$BUILD_DIR"
72
+ BUILD_DIR="$(cd "$BUILD_DIR" && pwd)"
73
+
74
+ VENV_DIR="$BUILD_DIR/.venv"
75
+ OUTPUT_DIR="$BUILD_DIR/pypi"
76
+
77
+ export BUILD_DIR # setup-env.sh reads this
78
+
79
+ # ── Colours / helpers (available before setup-env.sh) ────────────────────────
80
+ RED='\033[0;31m'
81
+ YELLOW='\033[1;33m'
82
+ CYAN='\033[0;36m'
83
+ GREEN='\033[0;32m'
84
+ NC='\033[0m'
85
+ info() { echo -e "${CYAN}[INFO]${NC} $*"; }
86
+ success() { echo -e "${GREEN}[OK]${NC} $*"; }
87
+ warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
88
+ fail() { echo -e "${RED}[FAIL]${NC} $*"; exit 1; }
89
+
90
+ # ── Source shared environment (creates/reuses the venv) ─────────────────────
91
+ # shellcheck disable=SC1091
92
+ source "${SCRIPT_DIR}/setup-env.sh"
93
+
94
+ # ── JupyterLite-specific setup ──────────────────────────────────────────────
23
95
  CONFIG_FILE="$SRC_DIR/jupyter_lite_config.json"
24
96
  REQUIREMENTS_FILE="$SRC_DIR/requirements.txt"
25
- PYTHON_BIN="${PYTHON_BIN:-$(command -v python3)}"
26
- BUILD_DIR="${2:-$SRC_DIR/build}"
27
- VENV_DIR="$BUILD_DIR/.venv"
28
- VENV_PYTHON="$VENV_DIR/bin/python"
29
97
  VENV_JUPYTER_LITE="$VENV_DIR/bin/jupyter-lite"
30
-
31
- if [[ -z "$PYTHON_BIN" ]] || ! command -v "$PYTHON_BIN" >/dev/null 2>&1; then
32
- echo "python3 executable not found. Set PYTHON_BIN to a valid Python interpreter."
33
- exit 1
98
+ PYPI="$OUTPUT_DIR" # wheels built by build-gen3sdk-lite land here
99
+
100
+ [[ -f "$REQUIREMENTS_FILE" ]] || fail "Missing requirements file: $REQUIREMENTS_FILE"
101
+ [[ -f "$CONFIG_FILE" ]] || fail "Missing config file: $CONFIG_FILE"
102
+
103
+ # For the free tier, skip reinstalling requirements when jupyter-lite is already
104
+ # present to preserve exact package versions set up by build-gen3sdk-lite.sh.
105
+ # For the remote tier, always install because its requirements.txt includes
106
+ # jupyterlite-remote-server which the free-tier build never installs.
107
+ #
108
+ if [[ "$TIER" == "free" && -x "$VENV_JUPYTER_LITE" ]]; then
109
+ info "Existing venv already has jupyter-lite — skipping requirements install"
110
+ else
111
+ info "Installing JupyterLite requirements …"
112
+ uv pip install --verbose -r "$REQUIREMENTS_FILE" 2>&1 | tail -5
113
+ success "JupyterLite requirements installed"
34
114
  fi
35
115
 
36
- if [[ ! -f "$REQUIREMENTS_FILE" ]]; then
37
- echo "Missing requirements file: $REQUIREMENTS_FILE"
38
- exit 1
39
- fi
116
+ [[ -x "$VENV_JUPYTER_LITE" ]] || \
117
+ fail "jupyter-lite executable not found in $VENV_DIR after dependency install."
40
118
 
41
- mkdir -p "$BUILD_DIR"
42
-
43
- "$PYTHON_BIN" -m venv "$VENV_DIR"
44
-
45
- "$VENV_PYTHON" -m pip install --upgrade pip
46
- "$VENV_PYTHON" -m pip install -r "$REQUIREMENTS_FILE"
47
-
48
- if [[ ! -x "$VENV_JUPYTER_LITE" ]]; then
49
- echo "jupyter-lite executable not found in $VENV_DIR after dependency install."
50
- exit 1
119
+ # ── Collect our own wheels for PipliteAddon ─────────────────────────────────
120
+ # With PyodideLockAddon disabled these flags are the ONLY route by which our
121
+ # wheels reach the browser. This only applies to the free tier
122
+ WHEEL_ARGS=()
123
+ WHEEL_COUNT=0
124
+ if [[ "$TIER" == "free" ]]; then
125
+ if [[ -d "$PYPI" ]]; then
126
+ info "Looking for wheels in $PYPI"
127
+ while IFS= read -r -d '' whl; do
128
+ WHEEL_ARGS+=(--piplite-wheels "$whl")
129
+ ((WHEEL_COUNT++)) || true
130
+ done < <(find "$PYPI" -maxdepth 1 -name "*.whl" -print0 | sort -z)
131
+ fi
132
+
133
+ if (( WHEEL_COUNT == 0 )); then
134
+ fail "No wheels found in $PYPI — run build-gen3sdk-lite.sh first."
135
+ fi
136
+ else
137
+ info "Skipping custom wheel collection for $TIER tier"
51
138
  fi
52
139
 
53
-
54
- echo "$VENV_JUPYTER_LITE" build \
55
- --config "$CONFIG_FILE" \
56
- --lite-dir "$SRC_DIR" \
57
- --output-dir "$BUILD_DIR/$TIER"
58
-
140
+ # ── Build ───────────────────────────────────────────────────────────────────
141
+ info "Running: jupyter-lite build ($TIER tier, ${WHEEL_COUNT} custom wheels)"
59
142
  "$VENV_JUPYTER_LITE" build \
60
143
  --config "$CONFIG_FILE" \
61
144
  --lite-dir "$SRC_DIR" \
62
- --output-dir "$BUILD_DIR/$TIER"
63
-
145
+ --output-dir "$BUILD_DIR/$TIER" \
146
+ ${WHEEL_ARGS[@]+"${WHEEL_ARGS[@]}"}
147
+
148
+ # ── Verify the site is self-contained ───────────────────────────────────────
149
+ # The whole point of vendoring the distribution is that nothing is fetched from
150
+ # a CDN at runtime. Check it here rather than discovering it as a browser hang.
151
+ LOCK_FILE="$BUILD_DIR/$TIER/static/pyodide/pyodide-lock.json"
152
+ if [[ -f "$LOCK_FILE" ]]; then
153
+ REMOTE_COUNT="$(python3 - "$LOCK_FILE" <<'PYEOF'
154
+ import json, sys
155
+ lock = json.load(open(sys.argv[1]))
156
+ remote = [
157
+ m.get("file_name", "")
158
+ for m in lock.get("packages", {}).values()
159
+ if "://" in m.get("file_name", "")
160
+ ]
161
+ print(len(remote))
162
+ for r in remote[:10]:
163
+ print(f" {r}", file=sys.stderr)
164
+ PYEOF
165
+ )"
166
+ if [[ "$REMOTE_COUNT" != "0" ]]; then
167
+ warn "$REMOTE_COUNT package(s) in pyodide-lock.json point at a remote host;"
168
+ warn " the browser will fetch these at runtime (see the sample above)."
169
+ else
170
+ success "pyodide-lock.json is fully local ($(ls -1 "$BUILD_DIR/$TIER/static/pyodide"/*.whl 2>/dev/null | wc -l | tr -d ' ') wheels)"
171
+ fi
172
+ else
173
+ warn "No pyodide-lock.json at $LOCK_FILE — is PyodideAddon.pyodide_url set?"
174
+ fi
64
175
 
176
+ PIPLITE_DIR="$BUILD_DIR/$TIER/static/pypi"
177
+ if [[ -d "$PIPLITE_DIR" ]]; then
178
+ success "piplite index: $(ls -1 "$PIPLITE_DIR"/*.whl 2>/dev/null | wc -l | tr -d ' ') wheels"
179
+ else
180
+ warn "No piplite index at $PIPLITE_DIR — our wheels did not reach the site."
181
+ fi
65
182
 
66
- echo "$TIER-tier JupyterLite build complete: $BUILD_DIR/$TIER (venv: $VENV_DIR)"
183
+ success "$TIER-tier JupyterLite build complete: $BUILD_DIR/$TIER"
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env bash
2
+ # =============================================================================
3
+ # setup-env.sh — Shared build-environment bootstrap
4
+ #
5
+ # Guarantees both build-gen3sdk-lite and build-jupyterlite use the same
6
+ # Python interpreter and virtual environment.
7
+ #
8
+ # BUILD_DIR resolution (first match wins):
9
+ # 1. Pre-set BUILD_DIR environment variable (export BUILD_DIR=…)
10
+ # 2. First positional argument (source setup-env.sh [/tmp/mybuild | ./mybuild])
11
+ # 3. Default: "builds"
12
+ #
13
+ # Usage:
14
+ # source setup-env.sh [build_dir]
15
+ #
16
+ # After sourcing, the venv at $BUILD_DIR/.venv is activated in the calling
17
+ # shell, and VENV_DIR is exported.
18
+ # =============================================================================
19
+
20
+ # ── Configuration ────────────────────────────────────────────────────────────
21
+ PYTHON_VERSION="3.14.2"
22
+
23
+ # Resolves a possibly-relative path against INIT_CWD (or $PWD) rather than
24
+ # whatever directory happens to be current when this runs.
25
+ _resolve_against_init_cwd() {
26
+ local path="$1"
27
+ local base="${INIT_CWD:-$(pwd)}"
28
+ case "$path" in
29
+ /*) printf '%s' "$path" ;;
30
+ *) printf '%s/%s' "$base" "$path" ;;
31
+ esac
32
+ }
33
+
34
+ BUILD_DIR="${BUILD_DIR:-$(_resolve_against_init_cwd "${1:-builds}")}"
35
+
36
+ mkdir -p "$BUILD_DIR"
37
+ BUILD_DIR="$(cd "$BUILD_DIR" && pwd)"
38
+
39
+ VENV_DIR="$BUILD_DIR/.venv"
40
+ export BUILD_DIR VENV_DIR PYTHON_VERSION
41
+
42
+ # ── Colours / helpers ────────────────────────────────────────────────────────
43
+ RED='\033[0;31m'
44
+ GREEN='\033[0;32m'
45
+ YELLOW='\033[1;33m'
46
+ CYAN='\033[0;36m'
47
+ NC='\033[0m'
48
+
49
+ info() { echo -e "${CYAN}[INFO]${NC} $*"; }
50
+ success() { echo -e "${GREEN}[OK]${NC} $*"; }
51
+ warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
52
+ fail() { echo -e "${RED}[FAIL]${NC} $*"; return 1 2>/dev/null || exit 1; }
53
+
54
+ # Export helpers so functions in the calling script can use them.
55
+ export -f info success warn fail
56
+
57
+ # ── uv ───────────────────────────────────────────────────────────────────────
58
+ if ! command -v uv &>/dev/null; then
59
+ fail "uv is not installed. Install it first: https://docs.astral.sh/uv/getting-started/installation/"
60
+ fi
61
+ success "uv found: $(uv --version)"
62
+
63
+ # ── Python (via uv) ─────────────────────────────────────────────────────────
64
+ info "Ensuring Python ${PYTHON_VERSION} is available via uv …"
65
+ uv python install "${PYTHON_VERSION}" 2>&1 | tail -1
66
+ success "Python ${PYTHON_VERSION} ready"
67
+
68
+ # ── Virtual environment (create once, reuse everywhere) ──────────────────────
69
+ if [[ ! -d "${VENV_DIR}" ]]; then
70
+ info "Creating virtual environment at ${VENV_DIR} …"
71
+ uv venv --python "${PYTHON_VERSION}" "${VENV_DIR}"
72
+ fi
73
+
74
+ # shellcheck disable=SC1091
75
+ source "${VENV_DIR}/bin/activate"
76
+ success "Activated venv ($(python --version))"
77
+
78
+ # ── Core Python tooling (idempotent — uv skips already-installed) ────────────
79
+ info "Ensuring core Python build tooling …"
80
+ uv pip install --upgrade pip build 2>&1 | tail -3
81
+ success "Core tooling ready"
@@ -1,12 +1,23 @@
1
1
  #!/usr/bin/env bash
2
2
  set -euo pipefail
3
3
 
4
-
5
- BUILD_SRC="${1:-}"
4
+ _resolve_against_init_cwd() {
5
+ local path="$1"
6
+ local base="${INIT_CWD:-$(pwd)}"
7
+ case "$path" in
8
+ /*) printf '%s' "$path" ;;
9
+ *) printf '%s/%s' "$base" "$path" ;;
10
+ esac
11
+ }
12
+
13
+ BUILD_SRC="$(_resolve_against_init_cwd "${1:-builds}")"
6
14
  if [[ -z "$BUILD_SRC" ]]; then
7
15
  usage "set to the output of the juypterlite install"
8
16
  fi
9
17
 
18
+
19
+ echo "Build directory is $BUILD_SRC"
20
+
10
21
  PKG_DIR="${2:-jupyter-workspaces}"
11
22
  echo "assets directory is: $PKG_DIR"
12
23
 
@@ -16,6 +27,7 @@ REMOTE_SRC="$BUILD_SRC/remote"
16
27
  FREE_DST="$PKG_DIR/assets/free"
17
28
  REMOTE_DST="$PKG_DIR/assets/remote"
18
29
  VALIDATE_SCRIPT="$SCRIPT_DIR/scripts/validate-jupyterlite-assets.sh"
30
+ source "${SCRIPT_DIR}/scripts/setup-env.sh"
19
31
 
20
32
  if [[ ! -d "$FREE_SRC" ]]; then
21
33
  echo "Missing free JupyterLite build output: $FREE_SRC"
@@ -29,6 +41,11 @@ if [[ ! -d "$REMOTE_SRC" ]]; then
29
41
  exit 1
30
42
  fi
31
43
 
44
+ echo $VALIDATE_SCRIPT
45
+ echo $FREE_SRC
46
+ echo $REMOTE_SRC
47
+
48
+
32
49
  bash "$VALIDATE_SCRIPT" --free-dir "$FREE_SRC" --remote-dir "$REMOTE_SRC"
33
50
 
34
51
  rm -rf "$FREE_DST" "$REMOTE_DST"
@@ -48,6 +48,9 @@ fi
48
48
  FREE_JSON="$FREE_DIR/jupyter-lite.json"
49
49
  REMOTE_JSON="$REMOTE_DIR/jupyter-lite.json"
50
50
 
51
+
52
+ echo "Free $FREE_DIR, Remote $REMOTE_DIR"
53
+
51
54
  if [[ ! -f "$FREE_JSON" ]]; then
52
55
  echo "Missing free config: $FREE_JSON"
53
56
  exit 1
@@ -3,24 +3,10 @@
3
3
  "apps": ["lab"],
4
4
  "output_dir": "site"
5
5
  },
6
- "LiteServerConfig": {
7
- "contents": ["./notebooks"],
8
- "settings_overrides": {
9
- "@jupyterlite/piplite-extension:plugin": {
10
- "pipliteDeps": [
11
- "numpy",
12
- "pandas",
13
- "scipy",
14
- "matplotlib",
15
- "seaborn",
16
- "biopython",
17
- "scanpy",
18
- "anndata",
19
- "pysam",
20
- "boto3",
21
- "s3fs"
22
- ]
23
- }
24
- }
6
+ "PyodideAddon": {
7
+ "pyodide_url": "https://github.com/pyodide/pyodide/releases/download/314.0.5/pyodide-314.0.5.tar.bz2"
8
+ },
9
+ "PyodideLockAddon": {
10
+ "enabled": false
25
11
  }
26
12
  }
@@ -1,3 +1,3 @@
1
1
  jupyterlite-core>=0.8.1
2
2
  jupyterlab>=4.6.0
3
- jupyterlite-pyodide-kernel
3
+ jupyterlite-pyodide-kernel[lock]
@@ -22,5 +22,21 @@
22
22
  "disabled": true
23
23
  }
24
24
  ]
25
+ },
26
+ "@jupyterlab/application-extension:context-menu": {
27
+ "contextMenu": [
28
+ {
29
+ "command": "filebrowser:download",
30
+ "selector": ".jp-DirListing-item[data-isdir=\"false\"]",
31
+ "rank": 9,
32
+ "disabled": true
33
+ },
34
+ {
35
+ "command": "filebrowser:copy-download-link",
36
+ "selector": ".jp-DirListing-item[data-isdir=\"false\"]",
37
+ "rank": 13,
38
+ "disabled": true
39
+ }
40
+ ]
25
41
  }
26
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gen3/workspaces",
3
- "version": "0.12.64",
3
+ "version": "0.12.66",
4
4
  "description": "Workspaces for Gen3",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -28,6 +28,8 @@
28
28
  "build": "npm run compile && npm run types && npm run rollup",
29
29
  "build:clean": "npm run clean && npm run build",
30
30
  "dev": "echo no dev tasks",
31
+ "build:jupyterlite:setupenv": "bash scripts/build-gen3sdk-lite.sh free",
32
+ "build:jupyterlite:gen3sdk": "bash scripts/build-gen3sdk-lite.sh free",
31
33
  "build:jupyterlite:free": "bash scripts/build-jupyterlite.sh free",
32
34
  "build:jupyterlite:remote": "bash scripts/build-jupyterlite.sh remote",
33
35
  "build:jupyterlite:all": "npm run build:jupyterlite:free && npm run build:jupyterlite:remote && npm run validate:jupyterlite:assets",
@@ -52,8 +54,8 @@
52
54
  "./jupyterlite-builds/*": "./dist/jupyterlite-builds/*"
53
55
  },
54
56
  "dependencies": {
55
- "@gen3/core": "^0.12.64",
56
- "@gen3/frontend": "^0.12.64",
57
+ "@gen3/core": "^0.12.66",
58
+ "@gen3/frontend": "^0.12.66",
57
59
  "camelcase-keys": "^10.0.2"
58
60
  },
59
61
  "peerDependencies": {