תוספים של Xuda

הקטגוריה בתוסף אינה תווית. היא כלל הניתוב.

שישים ושתיים חבילות מבית היוצר נשלחות היום, בשש קטגוריות בדיוק: 27 widget, 15 library, 10 ui, 5 graphics, 3 dbs ו-2 framework. הקטגוריה אינה מוסכמת שמות ואינה תגית. היא שדה plugin_type ברשומת התוסף, ושלוש מערכות נפרדות קוראות אותו: העורך מחליט באיזה שקע התוסף מופיע, האימות מחליט אילו קבצים עליו לייצא, וזמן הריצה מחליט על איזה משלושת משטחי ההרצה הקוד שלו רץ. שום דבר אינו מחווט ביד אחרי התקנה. חבילה אחת בקטלוג מוכיחה שהשדה הוא הסמכות ולא השם, משום שהתיקייה שלה והייצוא שלה אומרים שניהם widget בעוד ששם ה-npm שפורסם שלה אומר ui, וכל משטח ב-Studio מנתב אותה לפי השדה. פרויקט חדש מתחיל עם שני תוספים כבר מותקנים, מנהל ההתקן המקורי לנתונים ומסגרת Tailwind. כל מה שמעבר לשניים האלה הוא התקנה אחת, והקטגוריה קובעת היכן הוא נוחת.

שש קטגוריות, שישה שקעים שונים
תוסף ילד זקוק לכך שההורה שלו ינקוב בשמו בחזרה
קוד שרת של צד שלישי נדחה כברירת מחדל
הקטגוריה בתוסף אינה תווית. היא כלל הניתוב.
62

חבילות תוסף שנשלחו, על פני שש קטגוריות בדיוק

111

מתודות שמוצהרות על ידי 42 החבילות שמייצאות מתודות בכלל, על פני 632 שדות

6

שמות קבצים שהפלטפורמה מחפשת אחרי התקנה. רובן שולחות שניים

15

חבילות ששולחות קוד שרת. אף תוסף widget או ui אינו עושה זאת

כלל הניתוב

שש קטגוריות, והקטגוריה קובעת את שני הקצוות.

מתקינים אחד והוא מופיע במקום הנכון בלי שום דבר להגדיר, משום ששדה יחיד נקרא על ידי שישה חלקים שונים של העורך ועל ידי שלוש נקודות כניסה שונות של זמן הריצה. התמונה למטה היא החוזה, לא הבורר: בצד אחד כיצד מגיעים לתוסף מהקטגוריה הזאת, ובצד השני הייצוא המדויק שזמן הריצה קורא לו ובאיזו חתימה. יש לקרוא זאת כשישה חוזים עצמאיים שתלויים בשדה אחד ולא כממשק תוסף אחד בשישה טעמים, משום שזה מה שזה. תוסף widget ותוסף ui אינם מייצאים אותה צורה, אינם מקבלים אותם ארגומנטים ואינם מופיעים באותו מקום, ותוסף graphics אפילו אינו שולח את הקובץ שחמשת האחרים נבנים סביבו.

שתי הערות שוליים, שתיהן ניתנות לבדיקה. הקטגוריה היא שדה ברשומה ולא המילה שבשם החבילה, וחבילה אחת מוכיחה את ההבדל: התיקייה שלה והחוזה שלה אומרים widget, שם ה-npm שפורסם שלה אומר ui, וכל שקע שלמעלה מנתב אותה לפי השדה. וגם: תג המותקנים שמעל לוח ההוספה אינו סופר את כל שש הקטגוריות. הוא סופר רק framework, graphics ו-widget, משום ששלוש אלה הן היחידות שתורמות משהו שניתן לשחרר לתוך העמוד.
החוזה

חוזה אחד, שש צורות, והתאים הריקים הם הטיעון.

אחרי ה-npm install הפלטפורמה מחפשת שישה שמות קבצים, index.mjs, setup.mjs, studio.mjs, runtime.mjs, server.mjs ו-style.css. היא מסתכלת קודם בשורש החבילה ואחר כך בתוך dist, רושמת באיזה מהשניים היא מצאה כדי שזמן הריצה ידע אם לטעון גם את גיליון הסגנון הבנוי, ואז מייבאת כל קובץ שמצאה חוץ מ-style.css ומ-server.mjs. הייבוא הזה הוא בדיקת האם זה נטען האמיתית: תוסף שה-index.mjs שלו זורק שגיאה בזמן הייבוא נכשל באימות בו במקום ונוחת עם טקסט השגיאה שמור ברשומה שלו, וזו הסיבה שתוסף שבור מציג לך סיבה ולא משבצת ריקה. הטבלה למטה היא מה ששש הקטגוריות באמת שולחות. סימני האיקס נושאים חלק מהטיעון בדיוק כמו הטקסט: טור ה-server.mjs ריק בכל קטגוריה שפונה לדפדפן, וזו העובדה שגם משטחי ההרצה וגם שער הצד השלישי נשענים עליה. קובץ אחד הושמט מהטבלה במכוון. studio.mjs נשלח על ידי חבילה אחת בדיוק בכל הקטלוג, מנהל ההתקן המקורי לנתונים, שבו הוא משטח שרת נפרד לזמן העיצוב עבור העורך, ולכן הוא מקבל את המשפט הזה במקום טור של חמישה סימני איקס.

index.mjs חייב לייצא
runtime.mjs חייב לייצא
server.mjs
setup.mjs
widget, 27 נשלחוmethods, ובנוסף capabilities אופציונליפונקציה אחת לכל מתודה
library, 15 נשלחוmethodsנציג אחד לכל מתודה12 מתוך 1512 מתוך 15
ui, 10 נשלחוpropertiesfn, ואופציונלית destroy
graphics, 5 נשלחוtabs
dbs, 3 נשלחוtabs ו-public_filter3 מתוך 3
framework, 2 נשלחוtabs, core ופרימיטיבי הממשקcore, חובה. resources, אופציונלי
התקנה

התקנה היא npm install אמיתי לתוך תיקייה ששייכת לפרויקט שלך.

שום דבר כאן אינו מטאפורה להתקנה. רשומה נכתבת אל מפת התוספים שנרכשו בפרויקט, ונושאת את דגל ההתקנה, את הגרסה, את שם תוסף ההורה במקום שיש כזה, את מניפסט הקבצים, את סוג התוסף ואת דגל הרקע. אחר כך npm install רץ בתוך תיקיית תוספים ששייכת לפרויקט הזה בלבד, כשכל ארגומנט מצוטט לצורך המעטפת. אחר כך התיקייה הזאת מסונכרנת החוצה אל השרתים האזוריים. אחר כך החבילה המותקנת נסרקת עד עומק עשר וכל קובץ נקרא אל מסד נתונים של CouchDB ששייך לפרויקט, לפי הנתיב היחסי שלו, והגדרות קיימות נישאות דרך העדכון ולא נדרסות.

  • כל פרויקט מקבל עץ node_modules משלו, וחבילה שההורדה שלה נכשלת מסירה רק את עצמה. יש בקוד הערה שאומרת למה: גרסה מוקדמת יותר מחקה את כל העץ בכישלון, מה שהסיר את כל שאר התוספים שהיו לפרויקט משום שחבילה אחת לא הצליחה לרדת.
  • הסרה הופכת את דגל ההתקנה, מריצה npm uninstall, ומרוקנת את מסמך התוסף בצד הפרויקט עד למזהה שלו, לגרסה שלו ולהגדרות שלו. התצורה שורדת הסרה והתקנה מחדש מאוחר יותר, וזה ההבדל בין הסרת תוסף לבין איבוד פרטי ההזדהות שהקלדת בו.
  • שום דבר אינו נארז לתוך בניית האפליקציה. זמן הריצה מביא כל קובץ תוסף לכל הפעלה דרך נתיב /plugins, שמגיש מתוך העץ הייעודי לפרויקט ודורש או מזהה אפליקציה שניתן לפתור או אסימון תקף. עבור קובץ מקור שאינו ארוז, הנתיב הזה כותב מחדש את ייבואי ה-ESM היחסיים בדרך החוצה, כדי שדפדפן יוכל לטעון אותם בכלל. מה שהפריסה כן אורזת הוא מפת ההגדרות, שנאספת אל נתוני האתחול של האפליקציה.
  • בהפעלת פיתוח זמן הריצה מנסה את src לפני dist עבור כל קובץ .mjs ונופל חזרה אל dist, ולכן עריכת מקור התוסף מופיעה בלי בנייה מחדש. בכל מקום אחר המניפסט מכריע, ובמקום שבו הוא רושם שהעותק הבנוי הוא זה שנמצא, dist מנצח.
התקנה אחת
  1. הרשומה נכתבת
    התקנה, גרסה, שם ההורה, מניפסט הקבצים, סוג התוסף ודגל הרקע
  2. npm install רץ
    אל תיקיית התוספים של הפרויקט הזה בלבד, כשכל ארגומנט מצוטט לצורך המעטפת
  3. העץ מסונכרן החוצה
    תיקיית התוספים של הפרויקט נדחפת אל השרתים האזוריים המרוחקים
  4. החבילה מצולמת
    כל קובץ נקרא אל מסד הנתונים של הפרויקט, לפי הנתיב היחסי שלו
הרכבה

תוסף ילד נוקב בהורה שלו. ההורה חייב לנקוב בילד בחזרה.

תוסף רשאי להצהיר על הורה אחד, והפלטפורמה מסרבת להתקין אותו אלא אם שתי הצהרות נפרדות מסכימות. הילד נוקב בהורה דרך שדה תלות ברשומה שלו עצמו. ההורה חייב למנות את הילד בחזרה, במערך תוספים מורשים ברשומת ההורה. אף הצהרה אינה מספיקה לבדה. הבדיקות רצות בסדר וכל כישלון חוזר כסירוב ממוספר ולא כעקבות מחסנית, וכולן רצות לפני ש-npm מופעל, ולכן התקנה שנדחתה אינה משאירה דבר על הדיסק. אותן שתי בדיקות רצות שוב מאוחר יותר, בכל קריאה ובכל כתיבה של תצורת תוסף, ושוב בשרת לפני שמתודת תוסף מורשית לרוץ.

הזוג מכריע שני דברים מעבר להרשאה. חיפוש התצורה של ילד מופנה אל מסמך ההורה, ולכן יש תצורת Stripe אחת בדיוק ולא אחת לכל widget שמצייר שדה כרטיס. והוא מכריע אמון: משום שהשרת ממזג את קובץ השרת של ההורה אל אותו אובייקט שבו נמצא הילד, תוסף מבית היוצר שתלוי בתוסף של צד שלישי נחשב לצד שלישי.
תצורה

התוסף מחליט מה התצורה שלו עצמו רשאית לספר לדפדפן.

תצורת התוסף אינה מוחזקת במרשם המשותף. היא חיה כמסמך הגדרות בתוך מסד הנתונים של CouchDB של הפרויקט שהגדיר אותה, נכתבת על ידי טופס ההגדרות ונקראת בחזרה על ידי שני הצדדים. כשהקריאה היא ציבורית, הפלטפורמה מייבאת את התוסף וקוראת לפונקציה שהתוסף מייצא בעצמו, ושולחת בחזרה רק את מה שאותה פונקציה החזירה. אין רשימת היתר של מפתחות בטוחים ברמת הפלטפורמה, וזה גם החוזק של הסידור הזה וגם המגבלה שלו: מחבר התוסף הוא זה שיודע איזה מהשדות הוא הסוד, ומחבר התוסף הוא זה שכותב את המסנן.

הקריאה הכנה היא שהגבול הזה טוב בדיוק כמו התוסף שסימן אותו. מסנן חסר פירושו מסמך לא מסונן, והפלטפורמה אינה מפקפקת בכך. אותו מסמך הגדרות הוא מה ששלב הפריסה אוסף, רשומה אחת לכל תוסף מותקן, אל נתוני האתחול שאיתם האפליקציה נבנית.
הרצה

שלושה משטחים, וזה של השרת נבדק לפני הייבוא, לא אחריו.

קוד תוסף רץ בשלושה מקומות בדיוק. בדפדפן, כ-widget שבבעלותו מכל שזמן הריצה יצר עבורו, כתוסף ui שמעטר אלמנט שכבר היה לך, כמסגרת, או כתוסף רקע שמחובר למחזור החיים של האפליקציה. בשירות תוספים ייעודי, תהליך משלו על פורט 3008, עבור מתודות שרת של library. ובניתוב נפרד עבור מנהלי ההתקן של הנתונים, שאינו עובר דרך אותו שירות לעולם ושומר את החיבור החי שלו במטמון לכל אפליקציה ולכל תוסף. שני מסלולי השרת רצים תחת תקרה של שישים שניות.

  • מתודת library היא שני קבצים שעושים שתי עבודות. הנציג בדפדפן ממיר את השדות שהוצהרו, אוכף את שדות החובה ושולח; קובץ השרת עושה את העבודה ומחזיק את פרטי ההזדהות. הפיצול הזה הוא כל הסיבה לכך שלמפתח סודי של Stripe אין מסלול בדפדפן: הוא נקרא ב-server.mjs, מתוך מסמך ההגדרות שנמסר, ובשום מקום אחר.
  • לפני שהשירות טוען קובץ שרת של תוסף הוא שואל אם המפרסם הוא מבית היוצר, והוא שואל לפני הייבוא ולא אחריו. ייבוא מודול כבר מריץ את הקוד ברמה העליונה שלו, ולכן בדיקה שממוקמת אחריו אינה בודקת דבר. מתודות שרת של צד שלישי נדחות כברירת מחדל והמתג שהיה מתיר אותן מוגדר false בשתי התצורות, ולכן תוספי צד שלישי הם היום משטח מוצר בצד הדפדפן.
  • תוסף רקע מקבל חמישה ווים של מחזור חיים, שנורים בסדר beforeInit, initialized, beforeMounted, mounted ו-systemReady סביב הפעלת האפליקציה, וכל אחד מהם מקבל את ההפעלה, את אובייקט האפליקציה, את ה-api ואת נתוני ההגדרות. תיבת הסימון של הרצה ברקע מוצעת רק בתוסף library, והרישום מדולג לחלוטין במצב חבילה רזה.
  • השדות שמתודה מצהירה עליהם עושים עבודה כפולה. ב-Full Stack VPS הפלטפורמה עוברת על התוספים המותקנים ורושמת כל מתודה ככלי MCP, בשם התוסף ואחריו המתודה, כשסכמת הקלט שלו נבנית מאותם שדות מוצהרים והתיאור שלו נלקח מחלונית העזר שהמתודה כבר נשאה.
קריאת library אחת
  1. שלב תהליך העבודה נורה
    נוקב בתוסף, במתודה ובמאפיינים עבורה
  2. הנציג בדפדפן מאמת
    השדות מומרים לסוגים שהוצהרו, ושדות החובה נאכפים
  3. הוא שולח לשירות התוספים
    האסימון נבדק מול הפעלה חיה במסד הנתונים של הפרויקט שלך עצמך, לעולם לא ממטמון
  4. קובץ השרת רץ, עם תקרה
    שישים שניות, כשמסמך ההגדרות נמסר פנימה
מה קוד תוסף יכול להגיע אליו

תוסף בדפדפן מקבל אובייקט אחד, וזה כולו.

זמן הריצה בונה אובייקט פרמטרים אחד לכל קריאה ומוסר אותו כארגומנט השני. widget אינו מושיט יד אל משתנה גלובלי כדי למצוא את הפלטפורמה, ואין ממשק תוסף נפרד ללמוד מעבר למה שמגיע באותו אובייקט. המארח יוצר את ה-div של המכל, קורא את מזהה התוסף ואת שם המתודה מהצומת, מייבא את index.mjs ובודק את היכולות שהוצהרו מול הסביבה הנוכחית, פותר וממיר כל שדה שהוצהר ואוכף את שדות החובה, טוען את style.css ואת dist/runtime.css כשהמניפסט רשם אותם, מביא את הגדרות התוסף, ורק אז מייבא את runtime.mjs וממתין למתודה. שגיאה שנזרקת בתוך אותה מתודה נתפסת ומדווחת ולא מושארת להפיל את העמוד. הצורה שלמטה היא זו של widget. תוסף ui מקבל משהו שונה מספיק כדי שיהיה שווה להדפיס אותו לצידו, משום שההבדל הזה הוא כל ההבחנה בין שתי הקטגוריות: ל-widget ניתן מכל שבבעלותו, ולתוסף ui ניתן אלמנט שכבר היה לך.

runtime.mjs · export async function <method>(fields, params)
fields the declared fields, cast to their types and checked
params:
SESSION_ID, method, _session
dsP, sourceP, propsP datasource, source row, resolved props
plugin_name
container_node the div the runtime made for this widget
container_data
plugin_setup the filtered setup, never the raw document
report_error(desc, warn)
log_error(desc, warn)
call_plugin_api(name, data) the only route to the server
set_SYS_GLOBAL_OBJ_WIDGET_INFO(doc)
run_widgetCallbackEvent() fires the event id you declared as a field
api_utils
תוסף ui מקבל צורה שונה לגמרי:
fn(plugin_name, element, properties) no container, it decorates yours
זו מוסכמת קריאה, לא ארגז חול. קוד של widget רץ בעמוד שלך כמו כל סקריפט אחר בו, ומה שהאובייקט קונה לך הוא שהפלטפורמה מחליטה מה נכנס פנימה. תוסף ui רשאי לייצא גם destroy, כדי לשחרר את מה שבנה כשהאלמנט שלו נעלם, וזמן הריצה משחזר בדיוק את ה-properties שנמסרו ל-fn ולא פותר אותם מחדש בפירוק, משום שעד אז מקור הנתונים שמאחורי אותה שורה עשוי כבר להיות מוצא משימוש.
בניית תוסף

מסלול המפתחים הוא npm, ושום דבר בו אינו תוצרת בית.

אין כאן שרשרת כלים קניינית ואין ממשק שורת פקודה של תוספים ללמוד. כל המסלול הוא חבילת ארגז חול שפורסמה שמפתחים מולה, בניית ספרייה רגילה ב-Vite, ו-npm. הפלטפורמה פוגשת את התוסף שלך רק בסוף המסלול, כשרושמים את שם החבילה.

  1. 01

    פיתוח מול ארגז החול

    הרתמה היא חבילה אמיתית שפורסמה, @xuda.io/plugin-sandbox בגרסה 1.0.27. היא בונה עמוד בשתי חלוניות: טופס Plugin Configurator בצד אחד, שנוצר מהשדות שהמתודה שלך מצהירה עליהם, משנה גודל בגרירה באמצע, וחלונית Live Preview בצד השני עם ה-div של המכל שיימסר למתודה שלך. תפריט נפתח בוחר איזו מהמתודות שלך לבדוק. כל שדה שמצהיר על סוג התצוגה editor מקבל עורך Monaco אמיתי שמחובר לאירוע השינוי שלו, כשהשפה נלקחת מפרמטרי התצוגה ו-javascript היא ברירת המחדל. האימוץ חלקי ושווה לומר זאת בפשטות: שלוש עשרה מתוך שישים ושתיים החבילות שנשלחו מפתחות מולה, ועשרים שולחות עמוד בדיקה משלהן תחת tests.

  2. 02

    בנייה עם Vite, אל תוך dist

    כל חבילה שמשתמשת בארגז החול נושאת את אותה תצורת vite. נקודת הכניסה של הספרייה היא src/runtime.mjs, הפורמט הוא ES, ייבואים דינמיים מוטבעים פנימה, הפלט נוחת ב-dist, כל גיליון סגנון שנפלט משנה את שמו ל-runtime.css, ושלב העתקה קטן מעביר את כל מה שב-src חוץ מ-runtime.mjs אל dist לצידו. המוסכמה הזאת היא בדיוק הסיבה לכך שהפלטפורמה רושמת דגל dist ודגל css לכל קובץ כשהיא בודקת את החבילה שלך, והסיבה לכך שזמן הריצה יודע לטעון גם את dist/runtime.css וגם את המודול.

  3. 03

    פרסום, ואחר כך רישום

    כל שישים ושניים קובצי package.json שנשלחו נושאים סקריפט פרסום זהה: npm version patch, ואחריו npm publish. semver פשוט בלי שום דבר מעליו, וסימני המים הגבוהים מספרים כמה שימוש נעשה בזה. מנהל ההתקן המקורי לנתונים נמצא ב-1.0.320, מסגרת Tailwind ב-1.0.128, ובונה האפליקציות של ה-AI ב-1.0.74. רישום מול הפלטפורמה הוא שלב נפרד שמושך את המניפסט החי מ-npm, לוקח את הגרסה משם ולא מהטופס שלך, ולוקח את סמל השוק מתוך שדה svg_icon ב-package.json שלך אם השארת את הסמל בטופס ריק.

המסלול האחר

או שמתארים אותו, ומערכת התוספים בונה תוסף בעזרת תוסף.

הבונה אינו כלי שעוזר הצ'אט יכול להגיע אליו בכוחות עצמו. שתי המתודות שלו מסומנות פרטיות, ולכן שום דבר אינו חושף אותן ככלי סוכן; לשונית התוספים מכינה את הפעולה והעוזר מריץ אותה כחלק מאותה משימה. מה שעושה את העבודה הוא עצמו תוסף library שנשלח, בונה האפליקציות של Studio, ונקרא בדיוק כמו שכל מתודת library אחרת נקראת. כל אילוץ שלמטה נמצא במחולל ולא במסמך מדיניות, והמצב הסופי הוא תוסף פרטי, במכוון.

הגרסאות מצהירות על הכוונה: תוסף שנוצר הוא 0.1.0 ופעולת שינוי מקדמת את ספרת התיקון. הוא מקבל תחום npm משלו ולא את זה של בית היוצר, הוא מותקן מהפריט שנוצר ולא מהמרשם, והפיכתו לציבורי היא פעולה מפורשת נפרדת בכרטיס התוסף, וזה בדיוק מה שתשובת העוזר אומרת במילים מפורשות. וכעת התיקון הכן. הסריקה הזאת היא התאמת תבניות סטטית על טקסט שנוצר, שיושבת מעל סכמת תגובה ורשימת היתר של שבעה שמות קבצים. היא אינה ניתוח דינמי והיא אינה ארגז חול.
מי רשאי לעשות מה

חמש פעולות, ואין שתיים מהן שנחסמות באותה הדרך.

שתיים מאלה מתוארות דרך קבע כדבר אחד, והן אינן. חברות Agency חוסמת את עצם רישום התוסף, והיא יושבת על מתודת ההעלאה. חשבון מוכר פעיל ב-Stripe Connect חוסם את המעבר לציבורי, והוא יושב על מתודת הפרסום, שכל מי שמחובר רשאי לקרוא לה. הן עוצרות אנשים שונים ברגעים שונים. התקנת תוסף לפרויקט אינה נחסמת על ידי אף אחת מהן: היא דורשת הרשאת מנהל באותו פרויקט, ואם לתוסף יש מחיר היא מנותבת קודם דרך שלב תשלום.

הרשאה
תוכנית חברות
השער האחר
התקנה או הסרה בפרויקטמנהל פרויקטתוסף בתשלום מנותב קודם דרך שלב תשלום
קריאה או כתיבה של תצורת תוסףמנהל פרויקטשרשרת ההורים נבדקת מחדש לפני שנוגעים בכלום
עצם רישום התוסףמנהל פרויקטAgencyהבעלות נאכפת בכל עדכון
פרסום שלו בשוקכל משתמש מחוברחשבון מוכר פעיל ב-Stripe Connect, ואחרת 403
העברה שלו לארכיוןמנהל פרויקטהבעלים בלבד
השער

פרסום הוא פעולה נפרדת מעדכון הקוד, במכוון.

העלאת גרסה חדשה, או מתן אפשרות לבונה ה-AI לבנות אחת מחדש, לעולם אינה נכנסת שוב לביקורת. מחזור החיים הקיים נישא קדימה כלשונו: תוסף שהיה פרטי נשאר פרטי, תוסף שהיה ציבורי נשאר ציבורי, ומצב הביקורת שכבר היה לו הוא מצב הביקורת שהוא שומר. מעבר לציבורי הוא מתודה אחרת עם הרשאה אחרת, שרצה פעם אחת, על ידי הבעלים, במכוון, והיא הקריאה היחידה שמריצה את השער. כל מה שלמטה תלוי באותה קריאה אחת.

עשר בדיקות חוזרות מהמבקר, וכל אחת נושאת חומרה משלה: פעילות בוטים, כוונה מסחרית שלא נחשפה, קוד מזיק, פעילות חשודה, שם חשבון פגום, ספאם ואיכות נמוכה, התחזות וסימני מסחר, תוכן אסור, גניבה ספרותית ושכפול, וסודות או מידע אישי שדלפו. שווה לומר בפשטות מה נמסר למבקר, משום שזה קובע את התקרה של מה שכל פסיקה יכולה לומר: השם, התיאור, התגיות, הקטגוריה, המחיר, וסיכום קוד שהוא שם חבילת ה-npm, הגרסה שלה ורשימת הפלטפורמות. זו ביקורת מטא נתונים, לא קריאה של המקור שלך. מפרסם מבית היוצר מדלג עליה לגמרי. כל דבר שמוחזק עובר לאדם, עם דואר אלקטרוני למפעיל, כרטיס תמיכה שמנוכה כפילויות לפי מזהה הפריט, וקישור ערעור על דחייה, ואין שום יעד זמן טיפול כתוב בשום מקום בקוד.
מגבלות בכנות

תשעה דברים שמערכת התוספים אינה עושה.

  • תוספי צד שלישי אינם יכולים להריץ קוד שרת היום. המדיניות הזמנית היא דחייה, זהו מתג בקונפיג, והמתג הזה כבוי בשתי התצורות, ולכן כל מה שאתה בונה כדי שמישהו אחר יתקין הוא משטח בצד הדפדפן בלבד.
  • חוזה ה-widget נושא יכולת headless, עבור קוד תוסף שרץ במקום שאין בו מסמך. אף אחת מ-62 החבילות שנשלחו אינה מצהירה עליה. החוזה קיים, ההוכחה שנשלחה אינה קיימת.
  • זמן הריצה תומך בייצוא destroy אופציונלי בתוסף ui. אף אחד מעשרת תוספי ה-ui שנשלחו אינו מייצא אותו.
  • שניים משלושת מנהלי ההתקן לנתונים הם לקריאה בלבד כפי שנשלחו. רק המקורי מממש את כל שישה השירותים. MySQL ו-CouchDB מייצאים קריאה ובדיקת חיבור ולא יותר מזה, ובקשה מכל אחד מהם למשהו נוסף זורקת שגיאה תוך נקיבה בשירות החסר.
  • בורר הסמלים מחפש בתוך הערכה שבחרת, לא על פני הערכות שהתקנת. ותוסף graphics רשאי להצהיר על תלות npm אחת לכל היותר, וזו הסיבה שכל ערכה שנשלחה היא חבילת מקור אחת ועץ התיקיות שלה.
  • התקנת רכיב משותף בודקת רק שני סוגים של תלות בתוספים, מסגרת הממשק בתוכנית ומנהל ההתקן לנתונים בטבלה. רכיב שמשתמש בתוסף widget אינו מצהיר עליו, ולכן אותה התקנה יכולה להצליח כשה-widget עדיין חסר.
  • בונה ה-AI מוגן לפני שהקוד נארז, לעולם לא בזמן שהוא רץ. שלוש עשרה תבניות אסורות וערכה קבועה של שמות קבצים, שתיהן מוחלות על טקסט. אין מאחוריהן שום בידוד בזמן ריצה.
  • שום דבר בפלטפורמה אינו מחליט אילו מפתחות תצורה בטוחים לפרסום. שיקול הדעת הזה מואצל כולו למחבר התוסף, ותוסף שאינו מפעיל שיקול דעת מוסר את כל מסמך התצורה שלו לדפדפן.
  • מסלול הרישום מקבל שתי מחרוזות סוג יותר משהמוצר חושף, ושום דבר בקטלוג אינו שולח אף אחת מהן. השש שבבורר הן השש שמנתבות לאנשהו.
לפני שמתחייבים

השאלות שמתגבשות אצלך ברגע זה

חמש מתוך שש התשובות האלה מסתיימות במגבלה. הן כאן משום שהיית פוגש אותן בשבוע הראשון ממילא.

צפייה

צפייה בתוסף מותקן ומופיע בשקע שלו.

מתקינים שני תוספים ויש לך שכבת נתונים ומערכת עיצוב.

זה פשוטו כמשמעו מה שפרויקט חדש נשלח איתו: מנהל ההתקן המקורי לנתונים ומסגרת Tailwind, ולא יותר. כל מה שמעבר לשניים האלה הוא התקנה אחת, והקטגוריה שברשומה קובעת היכן הוא מופיע, בין אם זה לוח ההוספה, בורר הסמלים, בחירת מנהל ההתקן של הטבלה, מתג על אלמנט בודד, או רשימת פעולות תהליך העבודה.