Clepit
एक नज़र में
- श्रेणी
- डेवलपर प्लेटफ़ॉर्म
- वेबसाइट
- clepit.com
- कंसोल
- app.clepit.com
- दस्तावेज़
- clepit.com/en/docs
- GraphQL एपीआई
- api.clepit.com/graphql
- रियल-टाइम
- ws.clepit.com
- MCP सरफ़ेस
- api.clepit.com/mcp
- प्रकाशित पृष्ठ
- clepit.space
अधिकांश रिच टेक्स्ट डेटाबेस में HTML के एक ढेले के रूप में पहुँचता है। जब तक आप उसे दोबारा दिखाने के अलावा कुछ और नहीं करना चाहते, तब तक यह ठीक है: किसी ग्राहक का उल्लेख करने वाला हर पृष्ठ खोजना, उसी दस्तावेज़ को वेब पेज, ई-मेल और मोबाइल ऐप में दिखाना, या दो लोगों को एक साथ संपादन करने देना बिना किसी का अनुच्छेद खोए। तब तक शब्द और उनकी सजावट आपस में उलझ चुके होते हैं, और दस्तावेज़ को भरोसे से पढ़ पाने वाली एकमात्र चीज़ वही संपादक रह जाता है जिसने उसे लिखा था।
Clepit दोनों को अलग रखता है। एक पृष्ठ ब्लॉकों की सूची है, हर ब्लॉक एक छोटी, टाइप की हुई वस्तु, और दस्तावेज़ स्वयं JSON है: पार्स करने के लिए कोई मार्कअप नहीं, और पढ़ने के लिए किसी संपादक की ज़रूरत नहीं। यही कारण है कि संपादक अपने बल पर खड़ा रह सकता है। @clepit/core npm पर MIT लाइसेंस के अंतर्गत प्रकाशित है और होस्ट किए गए हिस्से के बारे में कुछ नहीं जानता, जबकि app.clepit.com का कार्यक्षेत्र वही दस्तावेज़ हैं जब उन्हें सहयोगी, अनुमतियाँ, इतिहास और सार्वजनिक वेब पर एक पता मिल जाता है।
पृष्ठ ब्लॉकों की एक सूची है
एक ब्लॉक चार क्षेत्रों का बना है: एक आईडी, एक प्रकार, वह डेटा जिसे वह प्रकार परिभाषित करता है, और उस पर लगाए गए समायोजन। एक अनुच्छेद के डेटा का आकार तालिका के डेटा से भिन्न होता है, और प्रकार ही बताता है कि किस आकार की अपेक्षा करनी है, इसलिए संग्रहित दस्तावेज़ केवल पार्स ही नहीं, जाँचा भी जा सकता है। पूरा पृष्ठ एक समय-चिह्न, एक संस्करण और क्रम में रखे ब्लॉक हैं, जो अपनी आँखों से पढ़ने और किसी पुल रिक्वेस्ट में समीक्षा करने लायक छोटा है। उसमें कहीं यह नहीं लिखा कि पृष्ठ कैसा दिखना चाहिए: वह उसका काम है जो उसे बना रहा है, और इसी से एक ही दस्तावेज़ बिना तीन प्रतियों के वेब पेज, ई-मेल और मोबाइल स्क्रीन बन पाता है।
बिना ब्राउज़र के दस्तावेज़ बनाना
रेंडरर कभी सीधे ब्राउज़र में नहीं लिखता। वह एक पतली परत के ज़रिए बनाता है जिसके पीछे दो आधार हैं: एक असली पृष्ठ-अंश बनाता है और दूसरा एक स्ट्रिंग, और वही ब्लॉक कोड दोनों पर चलता है। इसी तरह प्रकाशित पृष्ठ ऐसे सर्वर पर बनाया जाता है जहाँ कोई ब्राउज़र है ही नहीं, और इसी कारण सर्वर जो बनाता है वह वही दस्तावेज़ होता है जो संपादक ने दिखाया होता, न कि कोई दूसरा क्रियान्वयन जो धीरे-धीरे अलग पड़ जाए। स्ट्रिंग आधार एक सैनिटाइज़र को अनिवार्य तर्क के रूप में लेता है और जान-बूझकर उसका कोई डिफ़ॉल्ट नहीं है: पैकेज का सामान्य सैनिटाइज़र पार्स करने के लिए पहले एक पृष्ठ बनाता है, इसलिए वहाँ चल ही नहीं सकता, और चुपचाप एस्केपिंग पर लौट आना हर दस्तावेज़ की भीतरी सजावट बिना कुछ कहे छीन लेता। इसलिए यह कमी किसी डिफ़ॉल्ट में छिपाने के बजाय वहीं दिखती रहती है जहाँ उसका उपयोग होता है।
पढ़ने के लिए पाठक को कोई JavaScript नहीं चुकानी पड़ती
React अडैप्टर अपने दोनों हिस्सों को अलग-अलग भेजता है, क्योंकि दोनों की माँग उलटी है। कंटेंट कंपोनेंट सर्वर पर चलता है और पृष्ठ बनते समय ही तैयार मार्कअप निकाल देता है, इसलिए पाठक को दस्तावेज़ पहली ही प्रतिक्रिया में मिल जाता है। संपादक कंपोनेंट केवल क्लाइंट पर चलता है, क्योंकि वह संपादक का जीवनचक्र सँभालता है, और ब्राउज़र के बिना सँभालने को कुछ है ही नहीं। इसलिए Clepit का दस्तावेज़ पढ़ने के लिए ज़रा भी JavaScript नहीं चाहिए। लिखने के समय ही रनटाइम आता है।
एक पृष्ठ क्या-क्या रख सकता है
पैकेज के साथ छब्बीस तरह के ब्लॉक आते हैं। इनमें से अधिकांश वही हैं जो किसी भी संपादक को चाहिए: शीर्षक, अनुच्छेद, सूचियाँ, चेकलिस्ट, उद्धरण, कोड, तालिकाएँ, चित्र, ऑडियो, वीडियो, फ़ाइलें, सूचना-पेटियाँ और विभाजक। बाकी इसलिए हैं क्योंकि दस्तावेज़ लिखने में वे चीज़ें चाहिए होती हैं जिन्हें लेखन का औज़ार आम तौर पर छोड़ देता है। एक विषय-सूची जो दस्तावेज़ के शीर्षकों से स्वयं बनती है और हर एक से जोड़ती है। सिमटने वाले खंड और स्तंभ। एक कार्ड जो किसी दूसरे पृष्ठ की जगह खड़ा होता है। हाथ से बना रेखाचित्र। और एक गतिविधि ब्लॉक जो यह संग्रहित करता है कि किस दस्तावेज़ पर नज़र रखनी है, न कि उसकी गतिविधि की नक़ल, इसलिए वह उस दिन पर जमने के बजाय अभी जो हो रहा है वही दिखाता रहता है जिस दिन उसे डाला गया था। ब्लॉक के भीतर की सजावट में सामान्य चिह्न आते हैं, मोटा, तिरछा, रेखांकित, काटा हुआ, पंक्ति-भीतर कोड, उभार और लिंक, साथ ही टूलटिप, स्थिति-चिह्न और उल्लेख। पैकेज की स्वयं कोई रनटाइम निर्भरता नहीं है।
सूत्र और आरेख, पैकेज के भीतर ही बनाए गए
उन ब्लॉकों में से दो LaTeX और Mermaid दिखाते हैं, और दोनों पूरा काम पैकेज के भीतर ही करते हैं: स्रोत को पार्स करना, विन्यास निकालना, परिणाम बनाना। नीचे कोई रेंडरिंग लाइब्रेरी नहीं है और किसी सूत्र या प्रवाह-चित्र को तस्वीर में बदलने के लिए किसी सेवा को पुकारा भी नहीं जाता। यह निर्भरताओं के बारे में पसंद से कम और स्ट्रिंग आधार का परिणाम अधिक है। जो ब्लॉक केवल ब्राउज़र में मिलने वाली किसी चीज़ की ओर, या नेटवर्क की ओर हाथ बढ़ाता, वह उस सर्वर पर बन ही नहीं सकता था जो प्रकाशित पृष्ठ परोसता है, और तब वही पृष्ठ इस बात पर निर्भर करके अलग दिखता कि उसे किसने माँगा।
एक API संदर्भ जो पृष्ठ के भीतर ही रहता है
OpenAPI ब्लॉक को एक विनिर्देश दीजिए, चिपकाकर या पते से बताकर, और वह वही बनाता है जो विनिर्देश बताता है: संक्रियाएँ, उनके पथ और प्राचल, अनुरोध तथा प्रतिक्रिया की संरचनाएँ, और प्रमाणीकरण की विधि। हर संक्रिया के लिए वह cURL, TypeScript, Dart और Python में अनुरोध का एक नमूना भी बनाता है, जो विनिर्देश से उपजा है, न कि किसी ऐसे लेखक द्वारा टाइप किया गया जो उसे अद्यतन करना भूल जाएगा। embed ब्लॉक बाहरी दुनिया को इसी दृष्टि से देखता है: वह उन गिनी-चुनी सेवाओं को पहचानता है जिन्हें वह सचमुच दिखा सकता है, बाकी सबके लिए एक सादे लिंक को विफलता नहीं बल्कि उचित परिणाम मानता है, और जिस पते पर उसे भरोसा नहीं, उसे बनाने से साफ़ इनकार कर देता है।
एक ही अनुच्छेद में दो लोग
जो पृष्ठ अभी सीधे संपादित हो रहा है, उसे सर्वर पर एक ही कार्य सँभालता है, हर पृष्ठ के लिए एक, और हर बदलाव क्रम से उसी से होकर गुज़रता है। इसी से एक साथ किया जाने वाला संपादन समझ में आने लायक बनता है: पहले से होड़ करने वाला दूसरा लेखक है ही नहीं। दस्तावेज़ स्वयं एक CRDT है, इसलिए एक ही अनुच्छेद में लिखते दो लोग एक-दूसरे को मिटाने के बजाय आपस में मिल जाते हैं, और पीछे छूट गया कोई क्लाइंट दोनों ओर की कमी का आदान-प्रदान करके बराबरी कर लेता है। हर बदलाव किसी को भेजे जाने से पहले एक राइट-अहेड लॉग में जोड़ा जाता है, इसलिए दस्तावेज़ में मौजूद बाकी लोग जो देखते हैं वह पहले ही स्थायी रूप से दर्ज हो चुका होता है, केवल आगे बढ़ाया हुआ नहीं। अनुमति इंटरफ़ेस में नहीं, सर्वर पर लागू होती है: संपादन के अधिकार के बिना जुड़ने वाला कोई भी पढ़ने तक सीमित कर दिया जाता है, और दस्तावेज़ खुला रहने तक सत्र उस अधिकार की समय-समय पर फिर से जाँच करता है, ताकि छीना गया प्रवेश पृष्ठ दोबारा लोड होने की प्रतीक्षा किए बिना उसी व्यक्ति पर लागू हो जो पहले से टाइप कर रहा है।
हर लेखन एक ही दरवाज़े से गुज़रता है
किसी दस्तावेज़ को उसमें टाइप करता व्यक्ति भी बदल सकता है और API को पुकारता कोई प्रोग्राम भी, और ये दोनों रास्ते पहले एक ही पृष्ठ पर अलग-अलग लिख सकते थे। अब नहीं लिख सकते। API से आया लेखन उसी सत्र को सौंप दिया जाता है जो जीवित दस्तावेज़ को थामे है, और वहाँ वह चल रहे संपादनों के साथ एक ही लेन-देन के रूप में लागू होता है, इसलिए पृष्ठ क्या कहता है इस पर अलग-अलग राय रखने वाले दो लेखकों के बजाय घटनाओं का एक ही क्रम रहता है। दस्तावेज़ वापस लिखे जाने पर ब्लॉक की आईडी सुरक्षित रखी जाती हैं, क्योंकि टिप्पणियाँ उन्हीं पर टिकी हैं, और नई आईडी गढ़ने वाला कोई मिलान हर टिप्पणी को शून्य की ओर इशारा करता छोड़ जाता। और जब बना हुआ ब्लॉक-समूह पहले से संग्रहित समूह के बिलकुल समान हो, तो कुछ भी नहीं लिखा जाता।
वह एक मार्ग जहाँ मशीन कुंजी नहीं पहुँच सकती
एक निजी API कुंजी REST, GraphQL, GraphQL के सब्सक्रिप्शन सॉकेट और MCP पर काम करती है। सहयोग वाले सॉकेट पर वह काम नहीं करती, और यह जान-बूझकर है। हर साझा बदलाव पर उसे करने वाले व्यक्ति की मुहर लगती है, और वही मुहरें पृष्ठ के इतिहास में दर्ज कर्तृत्व बन जाती हैं। वहाँ संपादन करता कोई मशीन-पहचान ऐसा लेखक लिख देती जिसे किसी मनुष्य ने नहीं लिखा, और बाद में उसे पलटने का अर्थ एक पंक्ति मिटाना नहीं, इतिहास फिर से लिखना है। रेखा वेबसॉकेट और HTTP के बीच नहीं खिंची है: प्रश्न यह है कि वह मार्ग कर्तृत्व सहित इतिहास लिखता है या नहीं। नियम स्मृति से नहीं, कोड के आकार से लागू होता है, क्योंकि कुंजी स्वीकार करने के लिए जान-बूझकर किसी दूसरी प्रमाणीकरण पुकार पर जाना पड़ता है, और कोई मार्ग ऐसा करे तो एक परीक्षण विफल हो जाता है।
अपने ही पते पर एक कार्यक्षेत्र
हर कार्यक्षेत्र बनते ही अपने उपडोमेन वाला एक किरायेदार होता है, और किरायेदार उसी पते से तय होता है जिस पर अनुरोध आया था। इसलिए आप किस किरायेदार में हैं यह आपके किसी भी डेटा को पढ़े जाने से पहले ही तय हो जाता है, न कि बाद में लगाए गए किसी छन्ने से जिसे कोई भूल सकता है। उसके नीचे सीमा को स्वयं डेटाबेस पंक्ति-स्तरीय सुरक्षा से लागू करता है: हर अनुरोध एक कनेक्शन लेता है, उस पर पुकारने वाले की पहचान अंकित करता है, और कनेक्शन लौटने पर पूल उस स्थिति को मिटा देता है, ताकि एक अनुरोध की पहचान अगले अनुरोध की क्वेरियों में रिस न सके।
किसी डोमेन पर दावा करना उसे सिद्ध करना नहीं है
एंटरप्राइज़ योजना वाला कार्यक्षेत्र अपने पृष्ठ अपने ही डोमेन से परोस सकता है। किसी डोमेन पर दावा करना और उससे परोसना जान-बूझकर अलग-अलग चरण हैं: डोमेन बिना सत्यापन के संग्रहित होता है, और जब तक DNS में सत्यापन का रिकॉर्ड नहीं दिखता, रिज़ॉल्वर उसे पूरी तरह अनदेखा करता है। कोई भी किसी दूसरी कंपनी का पता किसी फ़ॉर्म में टाइप कर सकता है। पर उसे जीवित करने वाला रिकॉर्ड केवल वही प्रकाशित कर सकता है जिसका उस डोमेन पर नियंत्रण है।
पृष्ठ के अब तक के सारे संस्करण
Clepit एक अकेली वर्तमान स्थिति नहीं, बल्कि संस्करण रखता है। लोग काम करते रहते हैं और बीच-बीच में अपने आप स्नैपशॉट लिया जाता है, पर इस तरह सँभालकर कि साधारण टाइपिंग से सैकड़ों न बन जाएँ: दस मिनट बीत जाने पर या दस ब्लॉक बदल जाने पर, जो पहले हो, एक नया लिखा जाता है। पुनर्स्थापन एक ही लेन-देन है: पुराना स्नैपशॉट लगाया जाता है, ब्लॉक मिलाए जाते हैं, और पुनर्स्थापन स्वयं एक नए संस्करण के रूप में लिखा जाता है, ताकि पीछे लौटना चुपचाप मिटने के बजाय दर्ज हो। मिलान स्रोत की ब्लॉक आईडी जान-बूझकर बचाए रखता है, क्योंकि टिप्पणियाँ ब्लॉकों पर टिकी हैं, और नई आईडी के साथ पृष्ठ लौटाने पर उस पर की हर टिप्पणी बिना सहारे रह जाती।
उसे फिर से ढूँढ़ना
खोज पृष्ठों के एक प्रक्षेपण पर चलती है, और प्रश्न हाथ से SQL में जोड़े जाने के बजाय Postgres के अपने वेब-खोज विश्लेषक से होकर गुज़रता है, इसलिए कोई भी उद्धरण-चिह्न और ऋण-चिह्न टाइप कर सकता है और उनमें से कुछ भी इंजेक्शन की सतह नहीं बनता। पर साझा कार्यक्षेत्र में असली बात यह है कि अनुमति की जाँच कहाँ बैठी है। खोज पृष्ठों की तालिका से जुड़ती है, और उस तालिका की पंक्ति-स्तरीय सुरक्षा उसी जोड़ पर लागू होती है, इसलिए परिणाम पहले से ही उन्हीं पृष्ठों तक सीमित हैं जिन्हें पूछने वाला देख सकता है। छन्ने, यानी पृष्ठ-वृक्ष का कोई उपवृक्ष, अंतिम बार किसने संशोधित किया, अंतिम बार कब संपादित हुआ, उसके ऊपर अतिरिक्त शर्तों के रूप में जुड़ते हैं। इनमें से हर एक सीमित करता है; कोई भी चौड़ा नहीं कर सकता, क्योंकि वे सब उसी एक जाँच के पीछे बैठे हैं।
प्रकाशन जमा देता है, साझा करना नहीं
ये दो अलग चीज़ें हैं और Clepit जान-बूझकर इन्हें अलग-अलग बरतता है। किसी पृष्ठ को प्रकाशित करना वर्तमान दस्तावेज़ को एक संस्करण के रूप में जमा देता है, पृष्ठ को उसकी ओर इंगित करता है, और उसे सार्वजनिक बनाता है: कोई आगंतुक clepit.space पर, acme.clepit.space/handbook जैसे पते पर, जो पढ़ता है वह वही जमा हुआ संस्करण है, उसके बाद किए गए संपादन नहीं। प्रकाशन हटाने से ये संकेतक साफ़ हो जाते हैं पर सार्वजनिक पता बना रहता है, इसलिए बाद में फिर प्रकाशित करने पर वही URL लौट आता है, बजाय इसके कि उसकी ओर इशारा करते हर लिंक टूट जाएँ। साझा लिंक इसका उल्टा है: वह जीवित दस्तावेज़ परोसता है, इसलिए पाने वाला जो देखता है वह पृष्ठ के बदलने के साथ बदलता रहता है।
ऐसा लिंक जिसे आप वापस ले सकते हैं
साझा लिंक एक टोकन है जिसे आप निरस्त कर सकते हैं, और बनाते समय उसे समाप्ति की तिथि भी दी जा सकती है। संग्रहित केवल टोकन का हैश होता है, इसलिए लिंक बनते समय एक ही बार दिखता है और उसके बाद डेटाबेस से उसे वापस नहीं निकाला जा सकता, न हमारे द्वारा और न ही उस तक पहुँचने वाले किसी और के द्वारा। ये लिंक पढ़ने की अनुमति देते हैं, टिप्पणी की नहीं: टिप्पणी के लिए एक लेखक चाहिए, और लिंक थामे हुआ व्यक्ति लेखक नहीं है।
अपनी ही निर्देशिका से साइन इन
कोई कार्यक्षेत्र प्रमाणीकरण अपने ही पहचान प्रदाता को सौंप सकता है: बिज़नेस योजना पर OpenID Connect, एंटरप्राइज़ पर SAML, और उसके साथ निर्देशिका समन्वय के लिए SCIM। SCIM उसी उपयोगकर्ता संसाधन को सँभालता है जिसे Okta और Entra वास्तव में चलाते हैं, और मानक के सीधे पाठ से एक जान-बूझकर किया गया विचलन करता है: विलोपन सदस्य को मिटाने के बजाय निष्क्रिय कर देता है। विनिर्देश इसकी अनुमति देता है, और दूसरा विकल्प ऐसा निर्देशिका समन्वय है जो किसी को किसी समूह से हटाकर ही एक कार्यक्षेत्र की सारी सामग्री नष्ट कर सकता है।
इससे बात करने के चार रास्ते
REST /v1 के अंतर्गत चौवालीस संक्रियाएँ सँभालता है, जिनका वर्णन एक OpenAPI दस्तावेज़ करता है जो मार्गों से ही उत्पन्न होता है, उनके बगल में लिखा नहीं जाता; और सतत एकीकरण उस उत्पादन की तुलना संग्रह में रखी प्रति से करता है, इसलिए रजिस्ट्री को लाँघ जाने वाला कोई मार्ग-परिवर्तन चुपचाप नहीं आ सकता। GraphQL अनुप्रयोग के मॉडल को सँभालता है और सदस्यताएँ अपने ही सॉकेट पर ढोता है। रियलटाइम एक अलग प्रक्रिया है, इसीलिए गेटवे को दोबारा चालू करने पर अनुरोध की सतह उसके साथ नहीं गिरती; और वह कमरे के हिसाब से नहीं, सॉकेट के हिसाब से अनुमति देता है: हर घटना पर किरायेदार का हर कनेक्शन एक ही सामूहिक जाँच में परखा जाता है, और उसे केवल वही पाते हैं जिन्हें देखने की अनुमति है। MCP उन्हीं संक्रियाओं को AI एजेंटों के सामने औज़ारों के रूप में रखता है, और कोई भी औज़ार यह तय करने के लिए पुकारने वाले से आई आईडी पर भरोसा नहीं करता कि वह किस कार्यक्षेत्र में काम कर रहा है; लेखन उन्हीं सेवाओं से होकर जाता है जिन्हें इंटरफ़ेस इस्तेमाल करता है, इसलिए अनुमति की जाँच और ऑडिट का लेखा वही रहते हैं।
यह किसके लिए है
उन टीमों के लिए जिन्हें अपने नियंत्रण वाला संपादक चाहिए, और उन डेवलपर्स के लिए जो अपने उत्पाद में संरचित सामग्री जोड़ते हैं।
देखें Clepit: clepit.com