{"id":25492325,"url":"https://github.com/rundll86/fs-context","last_synced_at":"2025-04-10T00:16:14.270Z","repository":{"id":260909457,"uuid":"882686703","full_name":"Rundll86/fs-context","owner":"Rundll86","description":"New TS templates for developing Scratch Extension.","archived":false,"fork":false,"pushed_at":"2025-04-06T04:22:43.000Z","size":244,"stargazers_count":7,"open_issues_count":1,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-10T00:16:09.616Z","etag":null,"topics":["scratch","typescript","vue","webpack"],"latest_commit_sha":null,"homepage":"https://rundll86.github.io/fs-context","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Rundll86.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-11-03T13:51:42.000Z","updated_at":"2025-04-06T04:22:46.000Z","dependencies_parsed_at":"2025-02-14T09:21:47.673Z","dependency_job_id":"f067dd88-5c18-4383-bc9c-7c50fad1a67d","html_url":"https://github.com/Rundll86/fs-context","commit_stats":null,"previous_names":["rundll86/fs-context"],"tags_count":0,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rundll86%2Ffs-context","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rundll86%2Ffs-context/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rundll86%2Ffs-context/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Rundll86%2Ffs-context/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Rundll86","download_url":"https://codeload.github.com/Rundll86/fs-context/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248131315,"owners_count":21052819,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["scratch","typescript","vue","webpack"],"created_at":"2025-02-18T22:29:28.881Z","updated_at":"2025-04-10T00:16:14.251Z","avatar_url":"https://github.com/Rundll86.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# FS-Context 🦐\n**更优雅的开发通用Scratch拓展**\n\n\u003c/div\u003e\n\n## 概览\nFS-Context是一个易用的**TypeScript**上下文，用于更优雅的开发通用于*TurboWarp/GandiIDE*等ScratchMod的拓展。提供了一些拓展开发中较常用的工具/脚手架。\n\n## 优势\n- **更现代化的码风** 实现基于TypeScript和最新ES标准，简化繁琐的声明步骤并提供类型补全\n- **压缩代码和使用第三方库** 使用Webpack打包压缩JavaScript代码，允许导入第三方库\n- **平台通用加载器** 在各个平台均可自动加载拓展，无需轮子\n- **格式化+统一规范** 使用ESLint优化代码规范和风格\n- **通用翻译器** 解决l10n在各个平台实现不统一情况\n- **更优雅的积木和菜单声明** 在语法层用更优雅的方式生成声明，无需冗余符号\n- **Blockly注入模块完美支持** 动态参数框和文字重载，一步搞定！\n- **置前参数预加载** 输入的特定积木参数格式无需在实现内部额外编写加载代码\n- **通用工具集** 提供不同拓展间联动上下文和一些工具函数\n- **原版解析器** 解析并标准化原版菜单和积木文字的编写方式\n- **积木调试器 Waterbox（已弃用）** 有点鸡肋，不再赘述\n\n## 项目初衷\n不管在什么平台下，开发拓展都非常的折磨，\u003cu\u003e缺少类型提示/自动补全/代码不易读\u003c/u\u003e，以及不同平台对*runtime和vm*的沙盒机制都有严重差异。通用拓展需要编写非常多的并不必要的冗余代码。\n\n因此，本项目旨在提供一些*TS类型提示与工具集*，同时将不同平台加载拓展/获取vm等频繁且常用的操作封装，开发者不需要重复制造轮子，可以专注于**积木逻辑**的开发。\n\n## 对比\n（点击查看）\n\u003cdetails\u003e\n\u003csummary\u003e案例1：实现四则运算\u003c/summary\u003e\n\n\u003e TurboWarp\n```js\nclass MyExtension {\n    getInfo() {\n        return {\n            id: \"myextension\",\n            name: \"My Extension\",\n            blocks: [\n                {\n                    opcode: \"calc\",\n                    text: \"Calculate [a] [method] [b]\",\n                    arguments: {\n                        a: {\n                            type: Scratch.ArgumentType.NUMBER,\n                            defaultValue: 0\n                        },\n                        b: {\n                            type: Scratch.ArgumentType.NUMBER,\n                            defaultValue: 0\n                        },\n                        method: {\n                            menu: \"methods\"\n                        }\n                    },\n                    blockType: Scratch.BlockType.REPORTER\n                }\n            ],\n            menu: {\n                methods: [\n                    {\n                        text: \"加\",\n                        value: \"0\"\n                    },\n                    {\n                        text: \"减\",\n                        value: \"1\"\n                    },\n                    {\n                        text: \"乘\",\n                        value: \"2\"\n                    },\n                    {\n                        text: \"除\",\n                        value: \"3\"\n                    },\n                ]\n            }\n        }\n    }\n    calc(args) {\n        const methodMapper = [\n            (a, b) =\u003e a + b,\n            (a, b) =\u003e a - b,\n            (a, b) =\u003e a * b,\n            (a, b) =\u003e a / b,\n        ];\n        return methodMapper[args.method].call(null, args.a, args.b)\n    }\n}\nScratch.extensions.register(new MyExtension());\n```\n\u003e FS-Context\n```ts\nimport { Extension, BlockType, Menu } from \"@framework/structs\";\nexport default class MyExtension extends Extension {\n    id = \"myextension\";\n    name = \"My Extension\";\n    menus = [\n        new Menu(\"methods\", \"+ = 0, - = 1, * = 2, / = 3\")\n    ];\n    @BlockType.Reporter(\"Calculate [a:number=0] [method:menu=methods] [b:number=0]\")\n    calc({ a, method, b }) {\n        const methodMapper = [\n            (a, b) =\u003e a + b,\n            (a, b) =\u003e a - b,\n            (a, b) =\u003e a * b,\n            (a, b) =\u003e a / b,\n        ];\n        return methodMapper[method].call(null, a, b);\n    }\n};\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e案例2：实现三维向量乘积运算\u003c/summary\u003e\n\n\u003e TurboWarp\n```js\nclass MyExtension {\n    parseVector(data) {\n        const part = data.split(\" \");\n        part.push(0);\n        part.push(0);\n        return [\n            Scratch.Cast.toNumber(part[0]),\n            Scratch.Cast.toNumber(part[1]),\n            Scratch.Cast.toNumber(part[2])\n        ];\n    }\n    getInfo() {\n        return {\n            id: \"myextension\",\n            name: \"My Extension\",\n            blocks: [\n                {\n                    opcode: \"crossVector\",\n                    text: \"Product [a] cross [b]\",\n                    arguments: {\n                        a: {\n                            type: Scratch.ArgumentType.STRING,\n                            defaultValue: \"0 0\"\n                        },\n                        b: {\n                            type: Scratch.ArgumentType.STRING,\n                            defaultValue: \"0 0\"\n                        }\n                    },\n                    blockType: Scratch.BlockType.REPORTER\n                },\n                {\n                    opcode: \"dotVector\",\n                    text: \"Product [a] dot [b]\",\n                    arguments: {\n                        a: {\n                            type: Scratch.ArgumentType.STRING,\n                            defaultValue: \"0 0\"\n                        },\n                        b: {\n                            type: Scratch.ArgumentType.STRING,\n                            defaultValue: \"0 0\"\n                        }\n                    },\n                    blockType: Scratch.BlockType.REPORTER\n                }\n            ]\n        }\n    }\n    crossVector(args) {\n        const v1 = this.parseVector(args.a);\n        const v2 = this.parseVector(args.a);\n        return [\n            v1[1] * v2[2] - v1[2] * v2[1],\n            v1[2] * v2[0] - v1[0] * v2[2],\n            v1[0] * v2[1] - v1[1] * v2[0]\n        ];\n    }\n    dotVector(args) {\n        const v1 = this.parseVector(args.a);\n        const v2 = this.parseVector(args.a);\n        return v1.map((value, index) =\u003e value * v2[index]).reduce((sum, current) =\u003e sum + current, 0);\n    }\n}\nScratch.extensions.register(new MyExtension());\n```\n\u003e FS-Context\n```ts\nimport { Extension, BlockType, Menu } from \"@framework/structs\";\nexport default class MyExtension extends Extension {\n    id = \"myextension\";\n    name = \"My Extension\";\n    loaders = {\n        vector: {\n            load(src: string): [number, number, number] {\n                const parts: (number | string)[] = src.split(\" \");\n                parts.push(0);\n                parts.push(0);\n                return [\n                    Scratch.Cast.toNumber(parts[0]),\n                    Scratch.Cast.toNumber(parts[1]),\n                    Scratch.Cast.toNumber(parts[2])\n                ];\n            }\n        }\n    };\n    @BlockType.Reporter(\"Product [a:vector=0 0] cross [b:vector=0 0]\")\n    cross({ a, b }: { a: number[], b: number[] }) {\n        const v1 = a;\n        const v2 = b;\n        return [\n            v1[1] * v2[2] - v1[2] * v2[1],\n            v1[2] * v2[0] - v1[0] * v2[2],\n            v1[0] * v2[1] - v1[1] * v2[0]\n        ];\n    }\n    @BlockType.Reporter(\"Product [a:vector=0 0] dot [b:vector=0 0]\")\n    dot({ a, b }: { a: number[], b: number[] }) {\n        const v1 = a;\n        const v2 = b;\n        return v1.map((value, index) =\u003e value * v2[index]).reduce((sum, current) =\u003e sum + current, 0);\n    }\n};\n```\n\u003c/details\u003e\n\n不仅体积大量减少的同时也利用了许多最新的语言特性，让源代码更已读。\n# 完整文档\n[GithubIO](https://rundll86.github.io/fs-context)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frundll86%2Ffs-context","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frundll86%2Ffs-context","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frundll86%2Ffs-context/lists"}